/* GPRS LLC protocol implementation as per 3GPP TS 04.64 */

/* (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
 *
 * All Rights Reserved
 *
 * 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, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

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

#include <osmocore/msgb.h>
#include <osmocore/linuxlist.h>
#include <osmocore/timer.h>
#include <osmocore/talloc.h>

#include <openbsc/gsm_data.h>
#include <openbsc/debug.h>
#include <openbsc/gprs_sgsn.h>
#include <openbsc/gprs_gmm.h>
#include <openbsc/gprs_bssgp.h>
#include <openbsc/gprs_llc.h>
#include <openbsc/crc24.h>

LLIST_HEAD(gprs_llc_llmes);
void *llc_tall_ctx;

/* lookup LLC Entity based on DLCI (TLLI+SAPI tuple) */
static struct gprs_llc_lle *lle_by_tlli_sapi(uint32_t tlli, uint32_t sapi)
{
	struct gprs_llc_llme *llme;

	llist_for_each_entry(llme, &gprs_llc_llmes, list) {
		if (llme->tlli == tlli || llme->old_tlli == tlli)
			return &llme->lle[sapi];
	}
	return NULL;
}

static void lle_init(struct gprs_llc_llme *llme, uint32_t sapi)
{
	struct gprs_llc_lle *lle = &llme->lle[sapi];

	lle->llme = llme;
	lle->sapi = sapi;
	lle->state = GPRS_LLES_UNASSIGNED;

	/* FIXME: Initialize according to parameters from SAPI9 */

}

static struct gprs_llc_llme *llme_alloc(uint32_t tlli)
{
	struct gprs_llc_llme *llme;
	uint32_t i;

	llme = talloc_zero(llc_tall_ctx, struct gprs_llc_llme);
	if (!llme)
		return NULL;

	llme->tlli = tlli;
	llme->state = GPRS_LLMS_UNASSIGNED;

	for (i = 0; i < ARRAY_SIZE(llme->lle); i++)
		lle_init(llme, i);

	llist_add(&llme->list, &gprs_llc_llmes);

	return llme;
}

enum gprs_llc_cmd {
	GPRS_LLC_NULL,
	GPRS_LLC_RR,
	GPRS_LLC_ACK,
	GPRS_LLC_RNR,
	GPRS_LLC_SACK,
	GPRS_LLC_DM,
	GPRS_LLC_DISC,
	GPRS_LLC_UA,
	GPRS_LLC_SABM,
	GPRS_LLC_FRMR,
	GPRS_LLC_XID,
	GPRS_LLC_UI,
};

static const struct value_string llc_cmd_strs[] = {
	{ GPRS_LLC_NULL,	"NULL" },
	{ GPRS_LLC_RR,		"RR" },
	{ GPRS_LLC_ACK,		"ACK" },
	{ GPRS_LLC_RNR,		"RNR" },
	{ GPRS_LLC_SACK,	"SACK" },
	{ GPRS_LLC_DM,		"DM" },
	{ GPRS_LLC_DISC,	"DISC" },
	{ GPRS_LLC_UA,		"UA" },
	{ GPRS_LLC_SABM,	"SABM" },
	{ GPRS_LLC_FRMR,	"FRMR" },
	{ GPRS_LLC_XID,		"XID" },
	{ GPRS_LLC_UI,		"UI" },
	{ 0, NULL }
};

struct gprs_llc_hdr_parsed {
	uint8_t sapi;
	uint8_t is_cmd:1,
		 ack_req:1,
		 is_encrypted:1;
	uint32_t seq_rx;
	uint32_t seq_tx;
	uint32_t fcs;
	uint32_t fcs_calc;
	uint8_t *data;
	uint16_t data_len;
	enum gprs_llc_cmd cmd;
};

#define LLC_ALLOC_SIZE 16384
#define UI_HDR_LEN	3
#define N202		4
#define CRC24_LENGTH	3

static int gprs_llc_fcs(uint8_t *data, unsigned int len)
{
	uint32_t fcs_calc;

	fcs_calc = crc24_calc(INIT_CRC24, data, len);
	fcs_calc = ~fcs_calc;
	fcs_calc &= 0xffffff;

	return fcs_calc;
}

static void t200_expired(void *data)
{
	struct gprs_llc_lle *lle = data;

	/* 8.5.1.3: Expiry of T200 */

	if (lle->retrans_ctr >= lle->n200) {
		/* FIXME: LLGM-STATUS-IND, LL-RELEASE-IND/CNF */
		lle->state = GPRS_LLES_ASSIGNED_ADM;
	}

	switch (lle->state) {
	case GPRS_LLES_LOCAL_EST:
		/* FIXME: retransmit SABM */
		/* FIXME: re-start T200 */
		lle->retrans_ctr++;
		break;
	case GPRS_LLES_LOCAL_REL:
		/* FIXME: retransmit DISC */
		/* FIXME: re-start T200 */
		lle->retrans_ctr++;
		break;
	}

}

static void t201_expired(void *data)
{
	struct gprs_llc_lle *lle = data;

	if (lle->retrans_ctr < lle->n200) {
		/* FIXME: transmit apropriate supervisory frame (8.6.4.1) */
		/* FIXME: set timer T201 */
		lle->retrans_ctr++;
	}
}

int gprs_llc_tx_u(struct msgb *msg, uint8_t sapi, int command,
		  enum gprs_llc_u_cmd u_cmd, int pf_bit)
{
	uint8_t *fcs, *llch;
	uint8_t addr, ctrl;
	uint32_t fcs_calc;

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

	/* Address Field */
	addr = sapi & 0xf;
	if (command)
		addr |= 0x40;

	/* 6.3 Figure 8 */
	ctrl = 0xe0 | u_cmd;
	if (pf_bit)
		ctrl |= 0x10;

	/* prepend LLC UI header */
	llch = msgb_push(msg, 2);
	llch[0] = addr;
	llch[1] = ctrl;

	/* append FCS to end of frame */
	fcs = msgb_put(msg, 3);
	fcs_calc = gprs_llc_fcs(llch, fcs - llch);
	fcs[0] = fcs_calc & 0xff;
	fcs[1] = (fcs_calc >> 8) & 0xff;
	fcs[2] = (fcs_calc >> 16) & 0xff;

	/* Identifiers passed down: (BVCI, NSEI) */

	/* Send BSSGP-DL-UNITDATA.req */
	return gprs_bssgp_tx_dl_ud(msg, NULL);
}

/* Send XID response to LLE */
static int gprs_llc_tx_xid(struct gprs_llc_lle *lle, struct msgb *msg)
{
	/* copy identifiers from LLE to ensure lower layers can route */
	msgb_tlli(msg) = lle->llme->tlli;
	msgb_bvci(msg) = lle->llme->bvci;
	msgb_nsei(msg) = lle->llme->nsei;

	return gprs_llc_tx_u(msg, lle->sapi, 0, GPRS_LLC_U_XID, 1);
}

/* Transmit a UI frame over the given SAPI */
int gprs_llc_tx_ui(struct msgb *msg, uint8_t sapi, int command,
		   void *mmctx)
{
	struct gprs_llc_lle *lle;
	uint8_t *fcs, *llch;
	uint8_t addr, ctrl[2];
	uint32_t fcs_calc;
	uint16_t nu = 0;

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

	/* look-up or create the LL Entity for this (TLLI, SAPI) tuple */
	lle = lle_by_tlli_sapi(msgb_tlli(msg), sapi);
	if (!lle) {
		struct gprs_llc_llme *llme;
		llme = llme_alloc(msgb_tlli(msg));
		lle = &llme->lle[sapi];
	}
	/* Update LLE's (BVCI, NSEI) tuple */
	lle->llme->bvci = msgb_bvci(msg);
	lle->llme->nsei = msgb_nsei(msg);

	/* Increment V(U) */
	nu = lle->vu_send;
	lle->vu_send = (lle->vu_send + 1) % 512;

	/* Address Field */
	addr = sapi & 0xf;
	if (command)
		addr |= 0x40;

	/* Control Field */
	ctrl[0] = 0xc0;
	ctrl[0] |= nu >> 6;
	ctrl[1] = (nu << 2) & 0xfc;
	ctrl[1] |= 0x01; /* Protected Mode */

	/* prepend LLC UI header */
	llch = msgb_push(msg, 3);
	llch[0] = addr;
	llch[1] = ctrl[0];
	llch[2] = ctrl[1];

	/* append FCS to end of frame */
	fcs = msgb_put(msg, 3);
	fcs_calc = gprs_llc_fcs(llch, fcs - llch);
	fcs[0] = fcs_calc & 0xff;
	fcs[1] = (fcs_calc >> 8) & 0xff;
	fcs[2] = (fcs_calc >> 16) & 0xff;

	/* Identifiers passed down: (BVCI, NSEI) */

	/* Send BSSGP-DL-UNITDATA.req */
	return gprs_bssgp_tx_dl_ud(msg, mmctx);
}

static void gprs_llc_hdr_dump(struct gprs_llc_hdr_parsed *gph)
{
	DEBUGP(DLLC, "LLC SAPI=%u %c %c FCS=0x%06x(%s) ",
		gph->sapi, gph->is_cmd ? 'C' : 'R', gph->ack_req ? 'A' : ' ',
		gph->fcs, gph->fcs_calc == gph->fcs ? "correct" : "WRONG");

	if (gph->cmd)
		DEBUGPC(DLLC, "CMD=%s ", get_value_string(llc_cmd_strs, gph->cmd));

	if (gph->data)
		DEBUGPC(DLLC, "DATA ");

	DEBUGPC(DLLC, "\n");
}
static int gprs_llc_hdr_rx(struct gprs_llc_hdr_parsed *gph,
			   struct gprs_llc_lle *lle)
{
	switch (gph->cmd) {
	case GPRS_LLC_SABM: /* Section 6.4.1.1 */
		lle->v_sent = lle->v_ack = lle->v_recv = 0;
		if (lle->state == GPRS_LLES_ASSIGNED_ADM) {
			/* start re-establishment (8.7.1) */
		}
		lle->state = GPRS_LLES_REMOTE_EST;
		/* FIXME: Send UA */
		lle->state = GPRS_LLES_ABM;
		/* FIXME: process data */
		break;
	case GPRS_LLC_DISC: /* Section 6.4.1.2 */
		/* FIXME: Send UA */
		/* terminate ABM */
		lle->state = GPRS_LLES_ASSIGNED_ADM;
		break;
	case GPRS_LLC_UA: /* Section 6.4.1.3 */
		if (lle->state == GPRS_LLES_LOCAL_EST)
			lle->state = GPRS_LLES_ABM;
		break;
	case GPRS_LLC_DM: /* Section 6.4.1.4: ABM cannot be performed */
		if (lle->state == GPRS_LLES_LOCAL_EST)
			lle->state = GPRS_LLES_ASSIGNED_ADM;
		break;
	case GPRS_LLC_FRMR: /* Section 6.4.1.5 */
		break;
	case GPRS_LLC_XID: /* Section 6.4.1.6 */
		/* FIXME: implement XID negotiation using SNDCP */
		{
			struct msgb *resp;
			uint8_t *xid;
			resp = msgb_alloc_headroom(4096, 1024, "LLC_XID");
			xid = msgb_put(resp, gph->data_len);
			memcpy(xid, gph->data, gph->data_len);
			gprs_llc_tx_xid(lle, resp);
		}
		break;
	}

	return 0;
}

/* parse a GPRS LLC header, also check for invalid frames */
static int gprs_llc_hdr_parse(struct gprs_llc_hdr_parsed *ghp,
			      uint8_t *llc_hdr, int len)
{
	uint8_t *ctrl = llc_hdr+1;
	int is_sack = 0;
	unsigned int crc_length;
	uint32_t fcs_calc;

	if (len <= CRC24_LENGTH)
		return -EIO;

	crc_length = len - CRC24_LENGTH;

	ghp->ack_req = 0;

	/* Section 5.5: FCS */
	ghp->fcs = *(llc_hdr + len - 3);
	ghp->fcs |= *(llc_hdr + len - 2) << 8;
	ghp->fcs |= *(llc_hdr + len - 1) << 16;

	/* Section 6.2.1: invalid PD field */
	if (llc_hdr[0] & 0x80)
		return -EIO;

	/* This only works for the MS->SGSN direction */
	if (llc_hdr[0] & 0x40)
		ghp->is_cmd = 0;
	else
		ghp->is_cmd = 1;

	ghp->sapi = llc_hdr[0] & 0xf;

	/* Section 6.2.3: check for reserved SAPI */
	switch (ghp->sapi) {
	case 0:
	case 4:
	case 6:
	case 0xa:
	case 0xc:
	case 0xd:
	case 0xf:
		return -EINVAL;
	}

	if ((ctrl[0] & 0x80) == 0) {
		/* I (Information transfer + Supervisory) format */
		uint8_t k;

		ghp->data = ctrl + 3;

		if (ctrl[0] & 0x40)
			ghp->ack_req = 1;

		ghp->seq_tx  = (ctrl[0] & 0x1f) << 4;
		ghp->seq_tx |= (ctrl[1] >> 4);

		ghp->seq_rx  = (ctrl[1] & 0x7) << 6;
		ghp->seq_rx |= (ctrl[2] >> 2);

		switch (ctrl[2] & 0x03) {
		case 0:
			ghp->cmd = GPRS_LLC_RR;
			break;
		case 1:
			ghp->cmd = GPRS_LLC_ACK;
			break;
		case 2:
			ghp->cmd = GPRS_LLC_RNR;
			break;
		case 3:
			ghp->cmd = GPRS_LLC_SACK;
			k = ctrl[3] & 0x1f;
			ghp->data += 1 + k;
			break;
		}
		ghp->data_len = (llc_hdr + len - 3) - ghp->data;
	} else if ((ctrl[0] & 0xc0) == 0x80) {
		/* S (Supervisory) format */
		ghp->data = NULL;
		ghp->data_len = 0;

		if (ctrl[0] & 0x20)
			ghp->ack_req = 1;
		ghp->seq_rx  = (ctrl[0] & 0x7) << 6;
		ghp->seq_rx |= (ctrl[1] >> 2);

		switch (ctrl[1] & 0x03) {
		case 0:
			ghp->cmd = GPRS_LLC_RR;
			break;
		case 1:
			ghp->cmd = GPRS_LLC_ACK;
			break;
		case 2:
			ghp->cmd = GPRS_LLC_RNR;
			break;
		case 3:
			ghp->cmd = GPRS_LLC_SACK;
			break;
		}
	} else if ((ctrl[0] & 0xe0) == 0xc0) {
		/* UI (Unconfirmed Inforamtion) format */
		ghp->cmd = GPRS_LLC_UI;
		ghp->data = ctrl + 2;
		ghp->data_len = (llc_hdr + len - 3) - ghp->data;

		ghp->seq_tx  = (ctrl[0] & 0x7) << 6;
		ghp->seq_tx |= (ctrl[1] >> 2);
		if (ctrl[1] & 0x02) {
			ghp->is_encrypted = 1;
			/* FIXME: encryption */
		}
		if (ctrl[1] & 0x01) {
			/* FCS over hdr + all inf fields */
		} else {
			/* FCS over hdr + N202 octets (4) */
			if (crc_length > UI_HDR_LEN + N202)
				crc_length = UI_HDR_LEN + N202;
		}
	} else {
		/* U (Unnumbered) format: 1 1 1 P/F M4 M3 M2 M1 */
		ghp->data = NULL;
		ghp->data_len = 0;

		switch (ctrl[0] & 0xf) {
		case GPRS_LLC_U_NULL_CMD:
			ghp->cmd = GPRS_LLC_NULL;
			break;
		case GPRS_LLC_U_DM_RESP:
			ghp->cmd = GPRS_LLC_DM;
			break;
		case GPRS_LLC_U_DISC_CMD:
			ghp->cmd = GPRS_LLC_DISC;
			break;
		case GPRS_LLC_U_UA_RESP:
			ghp->cmd = GPRS_LLC_UA;
			break;
		case GPRS_LLC_U_SABM_CMD:
			ghp->cmd = GPRS_LLC_SABM;
			break;
		case GPRS_LLC_U_FRMR_RESP:
			ghp->cmd = GPRS_LLC_FRMR;
			break;
		case GPRS_LLC_U_XID:
			ghp->cmd = GPRS_LLC_XID;
			ghp->data = ctrl + 1;
			ghp->data_len = (llc_hdr + len - 3) - ghp->data;
			break;
		default:
			return -EIO;
		}
	}

	/* calculate what FCS we expect */
	ghp->fcs_calc = gprs_llc_fcs(llc_hdr, crc_length);

	/* FIXME: parse sack frame */
	if (ghp->cmd == GPRS_LLC_SACK) {
		LOGP(DLLC, LOGL_NOTICE, "Unsupported SACK frame\n");
		return -EIO;
	}

	return 0;
}

/* receive an incoming LLC PDU (BSSGP-UL-UNITDATA-IND, 7.2.4.2) */
int gprs_llc_rcvmsg(struct msgb *msg, struct tlv_parsed *tv)
{
	struct bssgp_ud_hdr *udh = (struct bssgp_ud_hdr *) msgb_bssgph(msg);
	struct gprs_llc_hdr *lh = msgb_llch(msg);
	struct gprs_llc_hdr_parsed llhp;
	struct gprs_llc_lle *lle;
	int rc = 0;

	/* Identifiers from DOWN: NSEI, BVCI, TLLI */

	memset(&llhp, 0, sizeof(llhp));
	rc = gprs_llc_hdr_parse(&llhp, (uint8_t *) lh, TLVP_LEN(tv, BSSGP_IE_LLC_PDU));
	gprs_llc_hdr_dump(&llhp);
	if (rc < 0) {
		LOGP(DLLC, LOGL_NOTICE, "Error during LLC header parsing\n");
		return rc;
	}

	if (llhp.fcs != llhp.fcs_calc) {
		LOGP(DLLC, LOGL_INFO, "Dropping frame with invalid FCS\n");
		return -EIO;
	}

	switch (gprs_tlli_type(msgb_tlli(msg))) {
	case TLLI_LOCAL:
	case TLLI_FOREIGN:
	case TLLI_RANDOM:
	case TLLI_AUXILIARY:
		break;
	default:
		LOGP(DLLC, LOGL_ERROR,
			"Discarding frame with strange TLLI type\n");
		break;
	}

	/* find the LLC Entity for this TLLI+SAPI tuple */
	lle = lle_by_tlli_sapi(msgb_tlli(msg), llhp.sapi);

	/* 7.2.1.1 LLC belonging to unassigned TLLI+SAPI shall be discarded,
	 * except UID and XID frames with SAPI=1 */
	if (!lle) {
		if (llhp.sapi == GPRS_SAPI_GMM &&
		    (llhp.cmd == GPRS_LLC_XID || llhp.cmd == GPRS_LLC_UI)) {
			struct gprs_llc_llme *llme;
			/* FIXME: don't use the TLLI but the 0xFFFF unassigned? */
			llme = llme_alloc(msgb_tlli(msg));
			lle = &llme->lle[llhp.sapi];
		} else {
			LOGP(DLLC, LOGL_NOTICE,
				"unknown TLLI/SAPI: Silently dropping\n");
			return 0;
		}
	}

	/* Update LLE's (BVCI, NSEI) tuple */
	lle->llme->bvci = msgb_bvci(msg);
	lle->llme->nsei = msgb_nsei(msg);

	/* Receive and Process the actual LLC frame */
	rc = gprs_llc_hdr_rx(&llhp, lle);
	if (rc < 0)
		return rc;

	/* llhp.data is only set when we need to send LL_[UNIT]DATA_IND up */
	if (llhp.data) {
		msgb_gmmh(msg) = llhp.data;
		switch (llhp.sapi) {
		case GPRS_SAPI_GMM:
			/* send LL_UNITDATA_IND to GMM */
			rc = gsm0408_gprs_rcvmsg(msg, lle->llme);
			break;
		case GPRS_SAPI_TOM2:
		case GPRS_SAPI_TOM8:
			/* FIXME: send LL_DATA_IND/LL_UNITDATA_IND to TOM */
		case GPRS_SAPI_SNDCP3:
		case GPRS_SAPI_SNDCP5:
		case GPRS_SAPI_SNDCP9:
		case GPRS_SAPI_SNDCP11:
			/* FIXME: send LL_DATA_IND/LL_UNITDATA_IND to SNDCP */
		case GPRS_SAPI_SMS:
			/* FIXME */
		default:
			LOGP(DLLC, LOGL_NOTICE, "Unsupported SAPI %u\n", llhp.sapi);
			rc = -EINVAL;
			break;
		}
	}

	return rc;
}

/* 04.64 Chapter 7.2.1.1 LLGMM-ASSIGN */
int gprs_llgmm_assign(struct gprs_llc_llme *llme,
		      uint32_t old_tlli, uint32_t new_tlli,
		      enum gprs_ciph_algo alg, const uint8_t *kc)
{
	unsigned int i;

	if (old_tlli == 0xffffffff && new_tlli != 0xffffffff) {
		/* TLLI Assignment 8.3.1 */
		/* New TLLI shall be assigned and used when (re)transmitting LLC frames */
		/* If old TLLI != 0xffffffff was assigned to LLME, then TLLI
		 * old is unassigned.  Only TLLI new shall be accepted when
		 * received from peer. */

		/* If TLLI old == 0xffffffff was assigned to LLME, then this is
		 * TLLI assignmemt according to 8.3.1 */
		llme->old_tlli = 0;
		llme->tlli = new_tlli;
		llme->state = GPRS_LLMS_ASSIGNED;
		/* 8.5.3.1 For all LLE's */
		for (i = 0; i < ARRAY_SIZE(llme->lle); i++) {
			struct gprs_llc_lle *l = &llme->lle[i];
			l->vu_send = l->vu_recv = 0;
			l->retrans_ctr = 0;
			l->state = GPRS_LLES_ASSIGNED_ADM;
			/* FIXME Set parameters according to table 9 */
		}
	} else if (old_tlli != 0xffffffff && new_tlli != 0xffffffff) {
		/* TLLI Change 8.3.2 */
		/* Both TLLI Old and TLLI New are assigned; use New when
		 * (re)transmitting.  Accept toth Old and New on Rx */
		llme->old_tlli = llme->tlli;
		llme->tlli = new_tlli;
		llme->state = GPRS_LLMS_ASSIGNED;
	} else if (old_tlli != 0xffffffff && new_tlli == 0xffffffff) {
		/* TLLI Unassignment 8.3.3) */
		llme->tlli = llme->old_tlli = 0;
		llme->state = GPRS_LLMS_UNASSIGNED;
		for (i = 0; i < ARRAY_SIZE(llme->lle); i++) {
			struct gprs_llc_lle *l = &llme->lle[i];
			l->state = GPRS_LLES_UNASSIGNED;
		}
	} else
		return -EINVAL;

	return 0;
}
