/* GPRS SNDCP protocol implementation as per 3GPP TS 04.65 */

/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
 * (C) 2010 by On-Waves
 *
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation; either version 3 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

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

#include <osmocom/core/msgb.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/talloc.h>
#include <osmocom/gprs/gprs_bssgp.h>

#include <openbsc/gsm_data.h>
#include <openbsc/debug.h>
#include <openbsc/gprs_llc.h>
#include <openbsc/sgsn.h>
#include <openbsc/gprs_sndcp.h>
#include <openbsc/gprs_llc_xid.h>
#include <openbsc/gprs_sndcp_xid.h>
#include <openbsc/gprs_sndcp_pcomp.h>
#include <openbsc/gprs_sndcp_comp.h>

#define DEBUG_IP_PACKETS 0	/* 0=Disabled, 1=Enabled */

#if DEBUG_IP_PACKETS == 1
/* Calculate TCP/IP checksum */
static uint16_t calc_ip_csum(uint8_t *data, int len)
{
	int i;
	uint32_t accumulator = 0;
	uint16_t *pointer = (uint16_t *) data;

	for (i = len; i > 1; i -= 2) {
		accumulator += *pointer;
		pointer++;
	}

	if (len % 2)
		accumulator += *pointer;

	accumulator = (accumulator & 0xffff) + ((accumulator >> 16) & 0xffff);
	accumulator += (accumulator >> 16) & 0xffff;
	return (~accumulator);
}

/* Calculate TCP/IP checksum */
static uint16_t calc_tcpip_csum(const void *ctx, uint8_t *packet, int len)
{
	uint8_t *buf;
	uint16_t csum;

	buf = talloc_zero_size(ctx, len);
	memset(buf, 0, len);
	memcpy(buf, packet + 12, 8);
	buf[9] = packet[9];
	buf[11] = (len - 20) & 0xFF;
	buf[10] = (len - 20) >> 8 & 0xFF;
	memcpy(buf + 12, packet + 20, len - 20);
	csum = calc_ip_csum(buf, len - 20 + 12);
	talloc_free(buf);
	return csum;
}

/* Show some ip packet details */
static void debug_ip_packet(uint8_t *data, int len, int dir, char *info)
{
	uint8_t tcp_flags;
	char flags_debugmsg[256];
	int len_short;
	static unsigned int packet_count = 0;
	static unsigned int tcp_csum_err_count = 0;
	static unsigned int ip_csum_err_count = 0;

	packet_count++;

	if (len > 80)
		len_short = 80;
	else
		len_short = len;

	if (dir)
		DEBUGP(DSNDCP, "%s: MS => SGSN: %s\n", info,
		       osmo_hexdump_nospc(data, len_short));
	else
		DEBUGP(DSNDCP, "%s: MS <= SGSN: %s\n", info,
		       osmo_hexdump_nospc(data, len_short));

	DEBUGP(DSNDCP, "%s: Length.: %d\n", info, len);
	DEBUGP(DSNDCP, "%s: NO.: %d\n", info, packet_count);

	if (len < 20) {
		DEBUGP(DSNDCP, "%s: Error: Short IP packet!\n", info);
		return;
	}

	if (calc_ip_csum(data, 20) != 0) {
		DEBUGP(DSNDCP, "%s: Bad IP-Header checksum!\n", info);
		ip_csum_err_count++;
	} else
		DEBUGP(DSNDCP, "%s: IP-Header checksum ok.\n", info);

	if (data[9] == 0x06) {
		if (len < 40) {
			DEBUGP(DSNDCP, "%s: Error: Short TCP packet!\n", info);
			return;
		}

		DEBUGP(DSNDCP, "%s: Protocol type: TCP\n", info);
		tcp_flags = data[33];

		if (calc_tcpip_csum(NULL, data, len) != 0) {
			DEBUGP(DSNDCP, "%s: Bad TCP checksum!\n", info);
			tcp_csum_err_count++;
		} else
			DEBUGP(DSNDCP, "%s: TCP checksum ok.\n", info);

		memset(flags_debugmsg, 0, sizeof(flags_debugmsg));
		if (tcp_flags & 1)
			strcat(flags_debugmsg, "FIN ");
		if (tcp_flags & 2)
			strcat(flags_debugmsg, "SYN ");
		if (tcp_flags & 4)
			strcat(flags_debugmsg, "RST ");
		if (tcp_flags & 8)
			strcat(flags_debugmsg, "PSH ");
		if (tcp_flags & 16)
			strcat(flags_debugmsg, "ACK ");
		if (tcp_flags & 32)
			strcat(flags_debugmsg, "URG ");
		DEBUGP(DSNDCP, "%s: FLAGS: %s\n", info, flags_debugmsg);
	} else if (data[9] == 0x11) {
		DEBUGP(DSNDCP, "%s: Protocol type: UDP\n", info);
	} else {
		DEBUGP(DSNDCP, "%s: Protocol type: (%02x)\n", info, data[9]);
	}

	DEBUGP(DSNDCP, "%s: IP-Header checksum errors: %d\n", info,
	       ip_csum_err_count);
	DEBUGP(DSNDCP, "%s: TCP-Checksum errors: %d\n", info,
	       tcp_csum_err_count);
}
#endif

/* Chapter 7.2: SN-PDU Formats */
struct sndcp_common_hdr {
	/* octet 1 */
	uint8_t nsapi:4;
	uint8_t more:1;
	uint8_t type:1;
	uint8_t first:1;
	uint8_t spare:1;
} __attribute__((packed));

/* PCOMP / DCOMP only exist in first fragment */
struct sndcp_comp_hdr {
	/* octet 2 */
	uint8_t pcomp:4;
	uint8_t dcomp:4;
} __attribute__((packed));

struct sndcp_udata_hdr {
	/* octet 3 */
	uint8_t npdu_high:4;
	uint8_t seg_nr:4;
	/* octet 4 */
	uint8_t npdu_low;
} __attribute__((packed));


static void *tall_sndcp_ctx;

/* A fragment queue entry, containing one framgent of a N-PDU */
struct defrag_queue_entry {
	struct llist_head list;
	/* segment number of this fragment */
	uint32_t seg_nr;
	/* length of the data area of this fragment */
	uint32_t data_len;
	/* pointer to the data of this fragment */
	uint8_t *data;
};

LLIST_HEAD(gprs_sndcp_entities);

/* Check if any compression parameters are set in the sgsn configuration */
static inline int any_pcomp_or_dcomp_active(struct sgsn_instance *sgsn) {
	if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive)
		return true;
	else
		return false;
}

/* Enqueue a fragment into the defragment queue */
static int defrag_enqueue(struct gprs_sndcp_entity *sne, uint8_t seg_nr,
			  uint8_t *data, uint32_t data_len)
{
	struct defrag_queue_entry *dqe;

	dqe = talloc_zero(tall_sndcp_ctx, struct defrag_queue_entry);
	if (!dqe)
		return -ENOMEM;
	dqe->data = talloc_zero_size(dqe, data_len);
	if (!dqe->data) {
		talloc_free(dqe);
		return -ENOMEM;
	}
	dqe->seg_nr = seg_nr;
	dqe->data_len = data_len;

	llist_add(&dqe->list, &sne->defrag.frag_list);

	if (seg_nr > sne->defrag.highest_seg)
		sne->defrag.highest_seg = seg_nr;

	sne->defrag.seg_have |= (1 << seg_nr);
	sne->defrag.tot_len += data_len;

	memcpy(dqe->data, data, data_len);

	return 0;
}

/* return if we have all segments of this N-PDU */
static int defrag_have_all_segments(struct gprs_sndcp_entity *sne)
{
	uint32_t seg_needed = 0;
	unsigned int i;

	/* create a bitmask of needed segments */
	for (i = 0; i <= sne->defrag.highest_seg; i++)
		seg_needed |= (1 << i);

	if (seg_needed == sne->defrag.seg_have)
		return 1;

	return 0;
}

static struct defrag_queue_entry *defrag_get_seg(struct gprs_sndcp_entity *sne,
						 uint32_t seg_nr)
{
	struct defrag_queue_entry *dqe;

	llist_for_each_entry(dqe, &sne->defrag.frag_list, list) {
		if (dqe->seg_nr == seg_nr) {
			llist_del(&dqe->list);
			return dqe;
		}
	}
	return NULL;
}

/* Perform actual defragmentation and create an output packet */
static int defrag_segments(struct gprs_sndcp_entity *sne)
{
	struct msgb *msg;
	unsigned int seg_nr;
	uint8_t *npdu;
	int npdu_len;
	int rc;
	uint8_t *expnd = NULL;

	LOGP(DSNDCP, LOGL_DEBUG, "TLLI=0x%08x NSAPI=%u: Defragment output PDU %u "
		"num_seg=%u tot_len=%u\n", sne->lle->llme->tlli, sne->nsapi,
		sne->defrag.npdu, sne->defrag.highest_seg, sne->defrag.tot_len);
	msg = msgb_alloc_headroom(sne->defrag.tot_len+256, 128, "SNDCP Defrag");
	if (!msg)
		return -ENOMEM;

	/* FIXME: message headers + identifiers */

	npdu = msg->data;

	for (seg_nr = 0; seg_nr <= sne->defrag.highest_seg; seg_nr++) {
		struct defrag_queue_entry *dqe;
		uint8_t *data;

		dqe = defrag_get_seg(sne, seg_nr);
		if (!dqe) {
			LOGP(DSNDCP, LOGL_ERROR, "Segment %u missing\n", seg_nr);
			msgb_free(msg);
			return -EIO;
		}
		/* actually append the segment to the N-PDU */
		data = msgb_put(msg, dqe->data_len);
		memcpy(data, dqe->data, dqe->data_len);

		/* release memory for the fragment queue entry */
		talloc_free(dqe);
	}

	npdu_len = sne->defrag.tot_len;

	/* FIXME: cancel timer */

	/* actually send the N-PDU to the SGSN core code, which then
	 * hands it off to the correct GTP tunnel + GGSN via gtp_data_req() */

	/* Decompress packet */
#if DEBUG_IP_PACKETS == 1
	DEBUGP(DSNDCP, "                                                   \n");
	DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n");
	DEBUGP(DSNDCP, "===================================================\n");
#endif
	if (any_pcomp_or_dcomp_active(sgsn)) {

		expnd = talloc_zero_size(msg, npdu_len + MAX_HDRDECOMPR_INCR);
		memcpy(expnd, npdu, npdu_len);

		/* Apply header decompression */
		rc = gprs_sndcp_pcomp_expand(expnd, npdu_len, sne->defrag.pcomp,
					     sne->defrag.proto);
		if (rc < 0) {
			LOGP(DSNDCP, LOGL_ERROR,
			     "TCP/IP Header decompression failed!\n");
			talloc_free(expnd);
			return -EIO;
		}

		/* Modify npu length, expnd is handed directly handed
		 * over to gsn_rx_sndcp_ud_ind(), see below */
		npdu_len = rc;
	} else
		expnd = npdu;
#if DEBUG_IP_PACKETS == 1
	debug_ip_packet(expnd, npdu_len, 1, "defrag_segments()");
	DEBUGP(DSNDCP, "===================================================\n");
	DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n");
	DEBUGP(DSNDCP, "                                                   \n");
#endif

	/* Hand off packet to gtp */
	rc = sgsn_rx_sndcp_ud_ind(&sne->ra_id, sne->lle->llme->tlli,
				  sne->nsapi, msg, npdu_len, expnd);

	if (any_pcomp_or_dcomp_active(sgsn))
		talloc_free(expnd);

	return rc;
}

static int defrag_input(struct gprs_sndcp_entity *sne, struct msgb *msg,
			uint8_t *hdr, unsigned int len)
{
	struct sndcp_common_hdr *sch;
	struct sndcp_udata_hdr *suh;
	uint16_t npdu_num;
	uint8_t *data;
	int rc;

	sch = (struct sndcp_common_hdr *) hdr;
	if (sch->first) {
		suh = (struct sndcp_udata_hdr *) (hdr + 1 + sizeof(struct sndcp_common_hdr));
	} else
		suh = (struct sndcp_udata_hdr *) (hdr + sizeof(struct sndcp_common_hdr));

	data = (uint8_t *)suh + sizeof(struct sndcp_udata_hdr);

	npdu_num = (suh->npdu_high << 8) | suh->npdu_low;

	LOGP(DSNDCP, LOGL_DEBUG, "TLLI=0x%08x NSAPI=%u: Input PDU %u Segment %u "
		"Length %u %s %s\n", sne->lle->llme->tlli, sne->nsapi, npdu_num,
		suh->seg_nr, len, sch->first ? "F " : "", sch->more ? "M" : "");

	if (sch->first) {
		/* first segment of a new packet.  Discard all leftover fragments of
		 * previous packet */
		if (!llist_empty(&sne->defrag.frag_list)) {
			struct defrag_queue_entry *dqe, *dqe2;
			LOGP(DSNDCP, LOGL_INFO, "TLLI=0x%08x NSAPI=%u: Dropping "
			     "SN-PDU %u due to insufficient segments (%04x)\n",
			     sne->lle->llme->tlli, sne->nsapi, sne->defrag.npdu,
			     sne->defrag.seg_have);
			llist_for_each_entry_safe(dqe, dqe2, &sne->defrag.frag_list, list) {
				llist_del(&dqe->list);
				talloc_free(dqe);
			}
		}
		/* store the currently de-fragmented PDU number */
		sne->defrag.npdu = npdu_num;

		/* Re-set fragmentation state */
		sne->defrag.no_more = sne->defrag.highest_seg = sne->defrag.seg_have = 0;
		sne->defrag.tot_len = 0;
		/* FIXME: (re)start timer */
	}

	if (sne->defrag.npdu != npdu_num) {
		LOGP(DSNDCP, LOGL_INFO, "Segment for different SN-PDU "
			"(%u != %u)\n", npdu_num, sne->defrag.npdu);
		/* FIXME */
	}

	/* FIXME: check if seg_nr already exists */
	/* make sure to subtract length of SNDCP header from 'len' */
	rc = defrag_enqueue(sne, suh->seg_nr, data, len - (data - hdr));
	if (rc < 0)
		return rc;

	if (!sch->more) {
		/* this is suppsed to be the last segment of the N-PDU, but it
		 * might well be not the last to arrive */
		sne->defrag.no_more = 1;
	}

	if (sne->defrag.no_more) {
		/* we have already received the last segment before, let's check
		 * if all the previous segments exist */
		if (defrag_have_all_segments(sne))
			return defrag_segments(sne);
	}

	return 0;
}

static struct gprs_sndcp_entity *gprs_sndcp_entity_by_lle(const struct gprs_llc_lle *lle,
						uint8_t nsapi)
{
	struct gprs_sndcp_entity *sne;

	llist_for_each_entry(sne, &gprs_sndcp_entities, list) {
		if (sne->lle == lle && sne->nsapi == nsapi)
			return sne;
	}
	return NULL;
}

static struct gprs_sndcp_entity *gprs_sndcp_entity_alloc(struct gprs_llc_lle *lle,
						uint8_t nsapi)
{
	struct gprs_sndcp_entity *sne;

	sne = talloc_zero(tall_sndcp_ctx, struct gprs_sndcp_entity);
	if (!sne)
		return NULL;

	sne->lle = lle;
	sne->nsapi = nsapi;
	sne->defrag.timer.data = sne;
	//sne->fqueue.timer.cb = FIXME;
	sne->rx_state = SNDCP_RX_S_FIRST;
	INIT_LLIST_HEAD(&sne->defrag.frag_list);

	llist_add(&sne->list, &gprs_sndcp_entities);

	return sne;
}

/* Entry point for the SNSM-ACTIVATE.indication */
int sndcp_sm_activate_ind(struct gprs_llc_lle *lle, uint8_t nsapi)
{
	LOGP(DSNDCP, LOGL_INFO, "SNSM-ACTIVATE.ind (lle=%p TLLI=%08x, "
	     "SAPI=%u, NSAPI=%u)\n", lle, lle->llme->tlli, lle->sapi, nsapi);

	if (gprs_sndcp_entity_by_lle(lle, nsapi)) {
		LOGP(DSNDCP, LOGL_ERROR, "Trying to ACTIVATE "
			"already-existing entity (TLLI=%08x, NSAPI=%u)\n",
			lle->llme->tlli, nsapi);
		return -EEXIST;
	}

	if (!gprs_sndcp_entity_alloc(lle, nsapi)) {
		LOGP(DSNDCP, LOGL_ERROR, "Out of memory during ACTIVATE\n");
		return -ENOMEM;
	}

	return 0;
}

/* Entry point for the SNSM-DEACTIVATE.indication */
int sndcp_sm_deactivate_ind(struct gprs_llc_lle *lle, uint8_t nsapi)
{
	struct gprs_sndcp_entity *sne;

	LOGP(DSNDCP, LOGL_INFO, "SNSM-DEACTIVATE.ind (lle=%p, TLLI=%08x, "
	     "SAPI=%u, NSAPI=%u)\n", lle, lle->llme->tlli, lle->sapi, nsapi);

	sne = gprs_sndcp_entity_by_lle(lle, nsapi);
	if (!sne) {
		LOGP(DSNDCP, LOGL_ERROR, "SNSM-DEACTIVATE.ind for non-"
		     "existing TLLI=%08x SAPI=%u NSAPI=%u\n", lle->llme->tlli,
		     lle->sapi, nsapi);
		return -ENOENT;
	}
	llist_del(&sne->list);
	/* frag queue entries are hierarchically allocated, so no need to
	 * free them explicitly here */
	talloc_free(sne);

	return 0;
}

/* Fragmenter state */
struct sndcp_frag_state {
	uint8_t frag_nr;
	struct msgb *msg;	/* original message */
	uint8_t *next_byte;	/* first byte of next fragment */

	struct gprs_sndcp_entity *sne;
	void *mmcontext;
};

/* returns '1' if there are more fragments to send, '0' if none */
static int sndcp_send_ud_frag(struct sndcp_frag_state *fs,
			      uint8_t pcomp, uint8_t dcomp)
{
	struct gprs_sndcp_entity *sne = fs->sne;
	struct gprs_llc_lle *lle = sne->lle;
	struct sndcp_common_hdr *sch;
	struct sndcp_comp_hdr *scomph;
	struct sndcp_udata_hdr *suh;
	struct msgb *fmsg;
	unsigned int max_payload_len;
	unsigned int len;
	uint8_t *data;
	int rc, more;

	fmsg = msgb_alloc_headroom(fs->sne->lle->params.n201_u+256, 128,
				   "SNDCP Frag");
	if (!fmsg) {
		msgb_free(fs->msg);
		return -ENOMEM;
	}

	/* make sure lower layers route the fragment like the original */
	msgb_tlli(fmsg) = msgb_tlli(fs->msg);
	msgb_bvci(fmsg) = msgb_bvci(fs->msg);
	msgb_nsei(fmsg) = msgb_nsei(fs->msg);

	/* prepend common SNDCP header */
	sch = (struct sndcp_common_hdr *) msgb_put(fmsg, sizeof(*sch));
	sch->nsapi = sne->nsapi;
	/* Set FIRST bit if we are the first fragment in a series */
	if (fs->frag_nr == 0)
		sch->first = 1;
	sch->type = 1;

	/* append the compression header for first fragment */
	if (sch->first) {
		scomph = (struct sndcp_comp_hdr *)
				msgb_put(fmsg, sizeof(*scomph));
		scomph->pcomp = pcomp;
		scomph->dcomp = dcomp;
	}

	/* append the user-data header */
	suh = (struct sndcp_udata_hdr *) msgb_put(fmsg, sizeof(*suh));
	suh->npdu_low = sne->tx_npdu_nr & 0xff;
	suh->npdu_high = (sne->tx_npdu_nr >> 8) & 0xf;
	suh->seg_nr = fs->frag_nr % 0xf;

	/* calculate remaining length to be sent */
	len = (fs->msg->data + fs->msg->len) - fs->next_byte;
	/* how much payload can we actually send via LLC? */
	max_payload_len = lle->params.n201_u - (sizeof(*sch) + sizeof(*suh));
	if (sch->first)
		max_payload_len -= sizeof(*scomph);
	/* check if we're exceeding the max */
	if (len > max_payload_len)
		len = max_payload_len;

	/* copy the actual fragment data into our fmsg */
	data = msgb_put(fmsg, len);
	memcpy(data, fs->next_byte, len);

	/* Increment fragment number and data pointer to next fragment */
	fs->frag_nr++;
	fs->next_byte += len;

	/* determine if we have more fragemnts to send */
	if ((fs->msg->data + fs->msg->len) <= fs->next_byte)
		more = 0;
	else
		more = 1;

	/* set the MORE bit of the SNDCP header accordingly */
	sch->more = more;

	rc = gprs_llc_tx_ui(fmsg, lle->sapi, 0, fs->mmcontext, true);
	/* abort in case of error, do not advance frag_nr / next_byte */
	if (rc < 0) {
		msgb_free(fs->msg);
		return rc;
	}

	if (!more) {
		/* we've sent all fragments */
		msgb_free(fs->msg);
		memset(fs, 0, sizeof(*fs));
		/* increment NPDU number for next frame */
		sne->tx_npdu_nr = (sne->tx_npdu_nr + 1) % 0xfff;
		return 0;
	}

	/* default: more fragments to send */
	return 1;
}

/* Request transmission of a SN-PDU over specified LLC Entity + SAPI */
int sndcp_unitdata_req(struct msgb *msg, struct gprs_llc_lle *lle, uint8_t nsapi,
			void *mmcontext)
{
	struct gprs_sndcp_entity *sne;
	struct sndcp_common_hdr *sch;
	struct sndcp_comp_hdr *scomph;
	struct sndcp_udata_hdr *suh;
	struct sndcp_frag_state fs;
	uint8_t pcomp = 0;
	uint8_t dcomp = 0;
	int rc;

	/* Identifiers from UP: (TLLI, SAPI) + (BVCI, NSEI) */

	/* Compress packet */
#if DEBUG_IP_PACKETS == 1
	DEBUGP(DSNDCP, "                                                   \n");
	DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n");
	DEBUGP(DSNDCP, "===================================================\n");
	debug_ip_packet(msg->data, msg->len, 0, "sndcp_initdata_req()");
#endif
	if (any_pcomp_or_dcomp_active(sgsn)) {

		/* Apply header compression */
		rc = gprs_sndcp_pcomp_compress(msg->data, msg->len, &pcomp,
					       lle->llme->comp.proto, nsapi);
		if (rc < 0) {
			LOGP(DSNDCP, LOGL_ERROR,
			     "TCP/IP Header compression failed!\n");
			return -EIO;
		}

		/* Fixup pointer locations and sizes in message buffer to match
		 * the new, compressed buffer size */
		msgb_get(msg, msg->len);
		msgb_put(msg, rc);
	}
#if DEBUG_IP_PACKETS == 1
	DEBUGP(DSNDCP, "===================================================\n");
	DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n");
	DEBUGP(DSNDCP, "                                                   \n");
#endif

	sne = gprs_sndcp_entity_by_lle(lle, nsapi);
	if (!sne) {
		LOGP(DSNDCP, LOGL_ERROR, "Cannot find SNDCP Entity\n");
		msgb_free(msg);
		return -EIO;
	}

	/* Check if we need to fragment this N-PDU into multiple SN-PDUs */
	if (msg->len > lle->params.n201_u - 
			(sizeof(*sch) + sizeof(*suh) + sizeof(*scomph))) {
		/* initialize the fragmenter state */
		fs.msg = msg;
		fs.frag_nr = 0;
		fs.next_byte = msg->data;
		fs.sne = sne;
		fs.mmcontext = mmcontext;

		/* call function to generate and send fragments until all
		 * of the N-PDU has been sent */
		while (1) {
			int rc = sndcp_send_ud_frag(&fs,pcomp,dcomp);
			if (rc == 0)
				return 0;
			if (rc < 0)
				return rc;
		}
		/* not reached */
		return 0;
	}

	/* this is the non-fragmenting case where we only build 1 SN-PDU */

	/* prepend the user-data header */
	suh = (struct sndcp_udata_hdr *) msgb_push(msg, sizeof(*suh));
	suh->npdu_low = sne->tx_npdu_nr & 0xff;
	suh->npdu_high = (sne->tx_npdu_nr >> 8) & 0xf;
	suh->seg_nr = 0;
	sne->tx_npdu_nr = (sne->tx_npdu_nr + 1) % 0xfff;

	scomph = (struct sndcp_comp_hdr *) msgb_push(msg, sizeof(*scomph));
	scomph->pcomp = pcomp;
	scomph->dcomp = dcomp;

	/* prepend common SNDCP header */
	sch = (struct sndcp_common_hdr *) msgb_push(msg, sizeof(*sch));
	sch->first = 1;
	sch->type = 1;
	sch->nsapi = nsapi;

	return gprs_llc_tx_ui(msg, lle->sapi, 0, mmcontext, true);
}

/* Section 5.1.2.17 LL-UNITDATA.ind */
int sndcp_llunitdata_ind(struct msgb *msg, struct gprs_llc_lle *lle,
			 uint8_t *hdr, uint16_t len)
{
	struct gprs_sndcp_entity *sne;
	struct sndcp_common_hdr *sch = (struct sndcp_common_hdr *)hdr;
	struct sndcp_comp_hdr *scomph = NULL;
	struct sndcp_udata_hdr *suh;
	uint8_t *npdu;
	uint16_t npdu_num __attribute__((unused));
	int npdu_len;
	int rc;
	uint8_t *expnd = NULL;

	sch = (struct sndcp_common_hdr *) hdr;
	if (sch->first) {
		scomph = (struct sndcp_comp_hdr *) (hdr + 1);
		suh = (struct sndcp_udata_hdr *) (hdr + 1 + sizeof(struct sndcp_common_hdr));
	} else
		suh = (struct sndcp_udata_hdr *) (hdr + sizeof(struct sndcp_common_hdr));

	if (sch->type == 0) {
		LOGP(DSNDCP, LOGL_ERROR, "SN-DATA PDU at unitdata_ind() function\n");
		return -EINVAL;
	}

	if (len < sizeof(*sch) + sizeof(*suh)) {
		LOGP(DSNDCP, LOGL_ERROR, "SN-UNITDATA PDU too short (%u)\n", len);
		return -EIO;
	}

	sne = gprs_sndcp_entity_by_lle(lle, sch->nsapi);
	if (!sne) {
		LOGP(DSNDCP, LOGL_ERROR, "Message for non-existing SNDCP Entity "
			"(lle=%p, TLLI=%08x, SAPI=%u, NSAPI=%u)\n", lle,
			lle->llme->tlli, lle->sapi, sch->nsapi);
		return -EIO;
	}
	/* FIXME: move this RA_ID up to the LLME or even higher */
	bssgp_parse_cell_id(&sne->ra_id, msgb_bcid(msg));

	if(scomph) {
		sne->defrag.pcomp = scomph->pcomp;
		sne->defrag.dcomp = scomph->dcomp;
		sne->defrag.proto = lle->llme->comp.proto;
		sne->defrag.data = lle->llme->comp.data;
	}

	/* any non-first segment is by definition something to defragment
	 * as is any segment that tells us there are more segments */
	if (!sch->first || sch->more)
		return defrag_input(sne, msg, hdr, len);

	npdu_num = (suh->npdu_high << 8) | suh->npdu_low;
	npdu = (uint8_t *)suh + sizeof(*suh);
	npdu_len = (msg->data + msg->len) - npdu - 3;	/* -3 'removes' the FCS */

	if (npdu_len <= 0) {
		LOGP(DSNDCP, LOGL_ERROR, "Short SNDCP N-PDU: %d\n", npdu_len);
		return -EIO;
	}
	/* actually send the N-PDU to the SGSN core code, which then
	 * hands it off to the correct GTP tunnel + GGSN via gtp_data_req() */

	/* Decompress packet */
#if DEBUG_IP_PACKETS == 1
	DEBUGP(DSNDCP, "                                                   \n");
	DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n");
	DEBUGP(DSNDCP, "===================================================\n");
#endif
	if (any_pcomp_or_dcomp_active(sgsn)) {

		expnd = talloc_zero_size(msg, npdu_len + MAX_HDRDECOMPR_INCR);
		memcpy(expnd, npdu, npdu_len);

		/* Apply header decompression */
		rc = gprs_sndcp_pcomp_expand(expnd, npdu_len, sne->defrag.pcomp,
					     sne->defrag.proto);
		if (rc < 0) {
			LOGP(DSNDCP, LOGL_ERROR,
			     "TCP/IP Header decompression failed!\n");
			talloc_free(expnd);
			return -EIO;
		}

		/* Modify npu length, expnd is handed directly handed
		 * over to gsn_rx_sndcp_ud_ind(), see below */
		npdu_len = rc;
	} else
		expnd = npdu;
#if DEBUG_IP_PACKETS == 1
	debug_ip_packet(expnd, npdu_len, 1, "sndcp_llunitdata_ind()");
	DEBUGP(DSNDCP, "===================================================\n");
	DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n");
	DEBUGP(DSNDCP, "                                                   \n");
#endif

	/* Hand off packet to gtp */
	rc = sgsn_rx_sndcp_ud_ind(&sne->ra_id, lle->llme->tlli,
				  sne->nsapi, msg, npdu_len, expnd);

	if (any_pcomp_or_dcomp_active(sgsn))
		talloc_free(expnd);

	return rc;
}

#if 0
/* Section 5.1.2.1 LL-RESET.ind */
static int sndcp_ll_reset_ind(struct gprs_sndcp_entity *se)
{
	/* treat all outstanding SNDCP-LLC request type primitives as not sent */
	/* reset all SNDCP XID parameters to default values */
	LOGP(DSNDCP, LOGL_NOTICE, "not implemented.\n");
	return 0;
}

static int sndcp_ll_status_ind()
{
	/* inform the SM sub-layer by means of SNSM-STATUS.req */
	LOGP(DSNDCP, LOGL_NOTICE, "not implemented.\n");
	return 0;
}

static struct sndcp_state_list {{
	uint32_t	states;
	unsigned int	type;
	int		(*rout)(struct gprs_sndcp_entity *se, struct msgb *msg);
} sndcp_state_list[] = {
	{ ALL_STATES,
	  LL_RESET_IND, sndcp_ll_reset_ind },
	{ ALL_STATES,
	  LL_ESTABLISH_IND, sndcp_ll_est_ind },
	{ SBIT(SNDCP_S_EST_RQD),
	  LL_ESTABLISH_RESP, sndcp_ll_est_ind },
	{ SBIT(SNDCP_S_EST_RQD),
	  LL_ESTABLISH_CONF, sndcp_ll_est_conf },
	{ SBIT(SNDCP_S_
};

static int sndcp_rx_llc_prim()
{
	case LL_ESTABLISH_REQ:
	case LL_RELEASE_REQ:
	case LL_XID_REQ:
	case LL_DATA_REQ:
	LL_UNITDATA_REQ,	/* TLLI, SN-PDU, Ref, QoS, Radio Prio, Ciph */

	switch (prim) {
	case LL_RESET_IND:
	case LL_ESTABLISH_IND:
	case LL_ESTABLISH_RESP:
	case LL_ESTABLISH_CONF:
	case LL_RELEASE_IND:
	case LL_RELEASE_CONF:
	case LL_XID_IND:
	case LL_XID_RESP:
	case LL_XID_CONF:
	case LL_DATA_IND:
	case LL_DATA_CONF:
	case LL_UNITDATA_IND:
	case LL_STATUS_IND:
}
#endif

/* Generate SNDCP-XID message */
static int gprs_llc_gen_sndcp_xid(uint8_t *bytes, int bytes_len, uint8_t nsapi)
{
	int entity = 0;
	LLIST_HEAD(comp_fields);
	struct gprs_sndcp_pcomp_rfc1144_params rfc1144_params;
	struct gprs_sndcp_comp_field rfc1144_comp_field;

	memset(&rfc1144_comp_field, 0, sizeof(struct gprs_sndcp_comp_field));

	/* Setup rfc1144 */
	if (sgsn->cfg.pcomp_rfc1144.active) {
		rfc1144_params.nsapi[0] = nsapi;
		rfc1144_params.nsapi_len = 1;
		rfc1144_params.s01 = sgsn->cfg.pcomp_rfc1144.s01;
		rfc1144_comp_field.p = 1;
		rfc1144_comp_field.entity = entity;
		rfc1144_comp_field.algo = RFC_1144;
		rfc1144_comp_field.comp[RFC1144_PCOMP1] = 1;
		rfc1144_comp_field.comp[RFC1144_PCOMP2] = 2;
		rfc1144_comp_field.comp_len = RFC1144_PCOMP_NUM;
		rfc1144_comp_field.rfc1144_params = &rfc1144_params;
		entity++;
		llist_add(&rfc1144_comp_field.list, &comp_fields);
	}

	/* Compile bytestream */
	return gprs_sndcp_compile_xid(bytes, bytes_len, &comp_fields);
}

/* Set of SNDCP-XID bnegotiation (See also: TS 144 065,
 * Section 6.8 XID parameter negotiation) */
int sndcp_sn_xid_req(struct gprs_llc_lle *lle, uint8_t nsapi)
{
	/* Note: The specification requires the SNDCP-User to set of an
	 * SNDCP xid request. See also 3GPP TS 44.065, 6.8 XID parameter
	 * negotiation, Figure 11: SNDCP XID negotiation procedure. In
	 * our case the SNDCP-User is sgsn_libgtp.c, which calls
	 * sndcp_sn_xid_req directly. */

	uint8_t l3params[1024];
	int xid_len;
	struct gprs_llc_xid_field xid_field_request;

	/* Wipe off all compression entities and their states to
	 * get rid of possible leftovers from a previous session */
	gprs_sndcp_comp_free(lle->llme->comp.proto);
	gprs_sndcp_comp_free(lle->llme->comp.data);
	lle->llme->comp.proto = gprs_sndcp_comp_alloc(lle->llme);
	lle->llme->comp.data = gprs_sndcp_comp_alloc(lle->llme);
	talloc_free(lle->llme->xid);
	lle->llme->xid = NULL;

	/* Generate compression parameter bytestream */
	xid_len = gprs_llc_gen_sndcp_xid(l3params, sizeof(l3params), nsapi);

	/* Send XID with the SNDCP-XID bytetsream included */
	if (xid_len > 0) {
		xid_field_request.type = GPRS_LLC_XID_T_L3_PAR;
		xid_field_request.data = l3params;
		xid_field_request.data_len = xid_len;
		return gprs_ll_xid_req(lle, &xid_field_request);
	}

	/* When bytestream can not be generated, proceed without SNDCP-XID */
	return gprs_ll_xid_req(lle, NULL);

}

/* Handle header compression entites */
static int handle_pcomp_entities(struct gprs_sndcp_comp_field *comp_field,
				 struct gprs_llc_lle *lle)
{
	/* Note: This functions also transforms the comp_field into its
	 * echo form (strips comp values, resets propose bit etc...)
	 * the processed comp_fields can then be sent back as XID-
	 * Response without further modification. */

	/* Delete propose bit */
	comp_field->p = 0;

	/* Process proposed parameters */
	switch (comp_field->algo) {
	case RFC_1144:
		if (sgsn->cfg.pcomp_rfc1144.passive
		    && comp_field->rfc1144_params->nsapi_len > 0) {
			DEBUGP(DSNDCP,
			       "Accepting RFC1144 header compression...\n");
			gprs_sndcp_comp_add(lle->llme, lle->llme->comp.proto,
					    comp_field);
		} else {
			DEBUGP(DSNDCP,
			       "Rejecting RFC1144 header compression...\n");
			gprs_sndcp_comp_delete(lle->llme->comp.proto,
					       comp_field->entity);
			comp_field->rfc1144_params->nsapi_len = 0;
		}
		break;
	case RFC_2507:
		/* RFC 2507 is not yet supported,
		 * so we set applicable nsapis to zero */
		DEBUGP(DSNDCP, "Rejecting RFC2507 header compression...\n");
		comp_field->rfc2507_params->nsapi_len = 0;
		gprs_sndcp_comp_delete(lle->llme->comp.proto,
				       comp_field->entity);
		break;
	case ROHC:
		/* ROHC is not yet supported,
		 * so we set applicable nsapis to zero */
		DEBUGP(DSNDCP, "Rejecting ROHC header compression...\n");
		comp_field->rohc_params->nsapi_len = 0;
		gprs_sndcp_comp_delete(lle->llme->comp.proto,
				       comp_field->entity);
		break;
	}

	return 0;
}

/* Hanle data compression entites */
static int handle_dcomp_entities(struct gprs_sndcp_comp_field *comp_field,
				 struct gprs_llc_lle *lle)
{
	/* See note in handle_pcomp_entities() */

	/* Delete propose bit */
	comp_field->p = 0;

	/* Process proposed parameters */
	switch (comp_field->algo) {
	case V42BIS:
		/* V42BIS is not yet supported,
		 * so we set applicable nsapis to zero */
		LOGP(DSNDCP, LOGL_DEBUG,
		     "Rejecting V.42bis data compression...\n");
		comp_field->v42bis_params->nsapi_len = 0;
		gprs_sndcp_comp_delete(lle->llme->comp.data,
				       comp_field->entity);
		break;
	case V44:
		/* V44 is not yet supported,
		 * so we set applicable nsapis to zero */
		DEBUGP(DSNDCP, "Rejecting V.44 data compression...\n");
		comp_field->v44_params->nsapi_len = 0;
		gprs_sndcp_comp_delete(lle->llme->comp.data,
				       comp_field->entity);
		break;
	}

	return 0;

}

/* Process SNDCP-XID indication
 * (See also: TS 144 065, Section 6.8 XID parameter negotiation) */
int sndcp_sn_xid_ind(struct gprs_llc_xid_field *xid_field_indication,
		     struct gprs_llc_xid_field *xid_field_response,
		     struct gprs_llc_lle *lle)
{
	/* Note: This function computes the SNDCP-XID response that is sent
	 * back to the ms when a ms originated XID is received. The
	 * Input XID fields are directly processed and the result is directly
	 * handed back. */

	int rc;
	int compclass;

	struct llist_head *comp_fields;
	struct gprs_sndcp_comp_field *comp_field;

	OSMO_ASSERT(xid_field_indication);
	OSMO_ASSERT(xid_field_response);
	OSMO_ASSERT(lle);

	/* Parse SNDCP-CID XID-Field */
	comp_fields = gprs_sndcp_parse_xid(lle->llme,
					   xid_field_indication->data,
					   xid_field_indication->data_len,
					   NULL);
	if (!comp_fields)
		return -EINVAL;

	/* Don't bother with empty indications */
	if (llist_empty(comp_fields)) {
		xid_field_response->data = NULL;
		xid_field_response->data_len = 0;
		DEBUGP(DSNDCP,
		       "SNDCP-XID indication did not contain any parameters!\n");
		return 0;
	}

	/* Handle compression entites */
	DEBUGP(DSNDCP, "SNDCP-XID-IND (ms):\n");
	gprs_sndcp_dump_comp_fields(comp_fields, LOGL_DEBUG);

	llist_for_each_entry(comp_field, comp_fields, list) {
		compclass = gprs_sndcp_get_compression_class(comp_field);
		if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION)
			rc = handle_pcomp_entities(comp_field, lle);
		else if (compclass == SNDCP_XID_DATA_COMPRESSION)
			rc = handle_dcomp_entities(comp_field, lle);
		else {
			gprs_sndcp_comp_delete(lle->llme->comp.proto,
					       comp_field->entity);
			gprs_sndcp_comp_delete(lle->llme->comp.data,
					       comp_field->entity);
			rc = 0;
		}

		if (rc < 0) {
			talloc_free(comp_fields);
			return -EINVAL;
		}
	}

	DEBUGP(DSNDCP, "SNDCP-XID-RES (sgsn):\n");
	gprs_sndcp_dump_comp_fields(comp_fields, LOGL_DEBUG);

	/* Reserve some memory to store the modified SNDCP-XID bytes */
	xid_field_response->data =
	    talloc_zero_size(lle->llme, xid_field_indication->data_len);

	/* Set Type flag for response */
	xid_field_response->type = GPRS_LLC_XID_T_L3_PAR;

	/* Compile modified SNDCP-XID bytes */
	rc = gprs_sndcp_compile_xid(xid_field_response->data,
				    xid_field_indication->data_len,
				    comp_fields);

	if (rc > 0)
		xid_field_response->data_len = rc;
	else {
		talloc_free(xid_field_response->data);
		xid_field_response->data = NULL;
		xid_field_response->data_len = 0;
		return -EINVAL;
	}

	talloc_free(comp_fields);

	return 0;
}

/* Process SNDCP-XID indication
 * (See also: TS 144 065, Section 6.8 XID parameter negotiation) */
int sndcp_sn_xid_conf(struct gprs_llc_xid_field *xid_field_conf,
		      struct gprs_llc_xid_field *xid_field_request,
		      struct gprs_llc_lle *lle)
{
	/* Note: This function handles an incomming SNDCP-XID confirmiation.
	 * Since the confirmation fields may lack important parameters we
	 * will reconstruct these missing fields using the original request
	 * we have sent. After that we will create (or delete) the
	 * compression entites */

	struct llist_head *comp_fields_req;
	struct llist_head *comp_fields_conf;
	struct gprs_sndcp_comp_field *comp_field;
	int rc;
	int compclass;

	/* We need both, the confirmation that is sent back by the ms,
	 * and the original request we have sent. If one of this is missing
	 * we can not process the confirmation, the caller must check if
	 * request and confirmation fields are available. */
	OSMO_ASSERT(xid_field_conf);
	OSMO_ASSERT(xid_field_request);

	/* Parse SNDCP-CID XID-Field */
	comp_fields_req = gprs_sndcp_parse_xid(lle->llme,
					       xid_field_request->data,
					       xid_field_request->data_len,
					       NULL);
	if (!comp_fields_req)
		return -EINVAL;

	DEBUGP(DSNDCP, "SNDCP-XID-REQ (sgsn):\n");
	gprs_sndcp_dump_comp_fields(comp_fields_req, LOGL_DEBUG);

	/* Parse SNDCP-CID XID-Field */
	comp_fields_conf = gprs_sndcp_parse_xid(lle->llme,
						xid_field_conf->data,
						xid_field_conf->data_len,
						comp_fields_req);
	if (!comp_fields_conf)
		return -EINVAL;

	DEBUGP(DSNDCP, "SNDCP-XID-CONF (ms):\n");
	gprs_sndcp_dump_comp_fields(comp_fields_conf, LOGL_DEBUG);

	/* Handle compression entites */
	llist_for_each_entry(comp_field, comp_fields_conf, list) {
		compclass = gprs_sndcp_get_compression_class(comp_field);
		if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION)
			rc = handle_pcomp_entities(comp_field, lle);
		else if (compclass == SNDCP_XID_DATA_COMPRESSION)
			rc = handle_dcomp_entities(comp_field, lle);
		else {
			gprs_sndcp_comp_delete(lle->llme->comp.proto,
					       comp_field->entity);
			gprs_sndcp_comp_delete(lle->llme->comp.data,
					       comp_field->entity);
			rc = 0;
		}

		if (rc < 0) {
			talloc_free(comp_fields_req);
			talloc_free(comp_fields_conf);
			return -EINVAL;
		}
	}

	talloc_free(comp_fields_req);
	talloc_free(comp_fields_conf);

	return 0;
}
