/* OpenBSC minimal LAPD implementation */

/* (C) 2009 by oystein@homelien.no
 * (C) 2011 by Harald Welte <laforge@gnumonks.org>
 * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
 * (C) 2010 by Digium and Matthew Fredrickson <creslin@digium.com>
 *
 * 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 <stdio.h>
#include <string.h>
#include <assert.h>
#include <errno.h>

#include "lapd.h"

#include <osmocore/linuxlist.h>
#include <osmocore/talloc.h>
#include <osmocore/msgb.h>
#include <openbsc/debug.h>

typedef enum {
	LAPD_TEI_NONE = 0,

	LAPD_TEI_ASSIGNED,

	LAPD_TEI_ACTIVE,
} lapd_tei_state;

const char *lapd_tei_states[] = {
	"NONE",
	"ASSIGNED",
	"ACTIVE",
};

typedef enum {
	LAPD_TYPE_NONE = 0,

	LAPD_TYPE_I,
	LAPD_TYPE_S,
	LAPD_TYPE_U,
} lapd_msg_type;

typedef enum {
	/* commands/responses */
	LAPD_CMD_NONE = 0,

	LAPD_CMD_I,
	LAPD_CMD_RR,
	LAPD_CMD_RNR,
	LAPD_CMD_REJ,

	LAPD_CMD_SABME,
	LAPD_CMD_DM,
	LAPD_CMD_UI,
	LAPD_CMD_DISC,
	LAPD_CMD_UA,
	LAPD_CMD_FRMR,
	LAPD_CMD_XID,
} lapd_cmd_type;

const char *lapd_cmd_types[] = {
	"NONE",

	"I",
	"RR",
	"RNR",
	"REJ",

	"SABME",
	"DM",
	"UI",
	"DISC",
	"UA",
	"FRMR",
	"XID",

};

const char *lapd_msg_types = "?ISU";

struct lapd_tei {
	struct llist_head list;

	uint8_t tei;
	/* A valid N(R) value is one that is in the range V(A) ≤ N(R) ≤ V(S). */
	int vs;			/* next to be transmitted */
	int va;			/* last acked by peer */
	int vr;			/* next expected to be received */
	lapd_tei_state state;
};

/* 3.5.2.2   Send state variable V(S)
 * Each point-to-point data link connection endpoint shall have an associated V(S) when using I frame
 * commands. V(S) denotes the sequence number of the next I frame to be transmitted. The V(S) can
 * take on the value 0 through n minus 1. The value of V(S) shall be incremented by 1 with each
 * successive I frame transmission, and shall not exceed V(A) by more than the maximum number of
 * outstanding I frames k. The value of k may be in the range of 1 ≤ k ≤ 127.
 *
 * 3.5.2.3   Acknowledge state variable V(A)
 * Each point-to-point data link connection endpoint shall have an associated V(A) when using I frame
 * commands and supervisory frame commands/responses. V(A) identifies the last I frame that has been
 * acknowledged by its peer [V(A) − 1 equals the N(S) of the last acknowledged I frame]. V(A) can
 * take on the value 0 through n minus 1. The value of V(A) shall be updated by the valid N(R) values
 * received from its peer (see 3.5.2.6). A valid N(R) value is one that is in the range V(A) ≤ N(R) ≤
 * V(S).
 *
 * 3.5.2.5    Receive state variable V(R)
 * Each point-to-point data link connection endpoint shall have an associated V(R) when using I frame
 * commands and supervisory frame commands/responses. V(R) denotes the sequence number of the
 * next in-sequence I frame expected to be received. V(R) can take on the value 0 through n minus 1.
 * The value of V(R) shall be incremented by one with the receipt of an error-free, in-sequence I frame
 * whose N(S) equals V(R).
 */
#define	LAPD_NS(teip) (teip->vs)
#define	LAPD_NR(teip) (teip->vr)

/* 3.5.2.4    Send sequence number N(S)
 * Only I frames contain N(S), the send sequence number of transmitted I frames. At the time that an in-
 * sequence I frame is designated for transmission, the value of N(S) is set equal to V(S).
 *
 * 3.5.2.6    Receive sequence number N(R)
 * All I frames and supervisory frames contain N(R), the expected send sequence number of the next
 * received I frame. At the time that a frame of the above types is designated for transmission, the value
 * of N(R) is set equal to V(R). N(R) indicates that the data link layer entity transmitting the N(R) has
 * correctly received all I frames numbered up to and including N(R) − 1.
 */

static struct lapd_tei *teip_from_tei(struct lapd_instance *li, uint8_t tei)
{
	struct lapd_tei *lt;

	llist_for_each_entry(lt, &li->tei_list, list) {
		if (lt->tei == tei)
			return lt;
	}
	return NULL;
};

static void lapd_tei_set_state(struct lapd_tei *teip, int newstate)
{
	DEBUGP(DMI, "state change on tei %d: %s -> %s\n", teip->tei,
		   lapd_tei_states[teip->state], lapd_tei_states[newstate]);
	teip->state = newstate;
};


int lapd_tei_alloc(struct lapd_instance *li, uint8_t tei)
{
	struct lapd_tei *teip;

	teip = talloc_zero(li, struct lapd_tei);
	if (!teip)
		return -ENOMEM;

	teip->tei = tei;
	llist_add(&teip->list, &li->tei_list);

	lapd_tei_set_state(teip, LAPD_TEI_ASSIGNED);

	return 0;
}

static void lapd_tei_receive(struct lapd_instance *li, uint8_t *data, int len)
{
	uint8_t entity = data[0];
	uint8_t ref = data[1];
	uint8_t mt = data[3];
	uint8_t action = data[4] >> 1;
	uint8_t e = data[4] & 1;
	uint8_t resp[8];
	struct lapd_tei *teip;

	DEBUGP(DMI, "TEIMGR: entity %x, ref %x, mt %x, action %x, e %x\n", entity, ref, mt, action, e);

	switch (mt) {
	case 0x01:	/* IDENTITY REQUEST */
		DEBUGP(DMI, "TEIMGR: identity request for TEI %u\n", action);

		teip = teip_from_tei(li, action);
		if (!teip) {
			LOGP(DMI, LOGL_INFO, "TEI MGR: New TEI %u\n", action);
			lapd_tei_alloc(li, action);
		}

		/* Send ACCEPT */
		memmove(resp, "\xfe\xff\x03\x0f\x00\x00\x02\x00", 8);
		resp[7] = (action << 1) | 1;
		li->transmit_cb(resp, 8, li->cbdata);

		if (teip->state == LAPD_TEI_NONE)
			lapd_tei_set_state(teip, LAPD_TEI_ASSIGNED);
		break;
	default:
		LOGP(DMI, LOGL_NOTICE, "TEIMGR: unknown mt %x action %x\n",
		     mt, action);
		break;
	};
};

uint8_t *lapd_receive(struct lapd_instance *li, uint8_t * data, unsigned int len,
		      int *ilen, lapd_mph_type *prim)
{
	uint8_t sapi, cr, tei, command;
	int pf, ns, nr;
	uint8_t *contents;
	struct lapd_tei *teip;

	uint8_t resp[8];
	int l = 0;

	*ilen = 0;
	*prim = 0;

	if (len < 2) {
		DEBUGP(DMI, "len %d < 2\n", len);
		return NULL;
	};

	if ((data[0] & 1) != 0 || (data[1] & 1) != 1) {
		DEBUGP(DMI, "address field %x/%x not well formed\n", data[0],
			   data[1]);
		return NULL;
	};

	sapi = data[0] >> 2;
	cr = (data[0] >> 1) & 1;
	tei = data[1] >> 1;
	command = li->network_side ^ cr;
	//DEBUGP(DMI, "  address sapi %x tei %d cmd %d cr %d\n", sapi, tei, command, cr);

	if (len < 3) {
		DEBUGP(DMI, "len %d < 3\n", len);
		return NULL;
	};

	lapd_msg_type typ = 0;
	lapd_cmd_type cmd = 0;
	pf = -1;
	ns = -1;
	nr = -1;
	if ((data[2] & 1) == 0) {
		typ = LAPD_TYPE_I;
		assert(len >= 4);
		ns = data[2] >> 1;
		nr = data[3] >> 1;
		pf = data[3] & 1;
		cmd = LAPD_CMD_I;
	} else if ((data[2] & 3) == 1) {
		typ = LAPD_TYPE_S;
		assert(len >= 4);
		nr = data[3] >> 1;
		pf = data[3] & 1;
		switch (data[2]) {
		case 0x1:
			cmd = LAPD_CMD_RR;
			break;
		case 0x5:
			cmd = LAPD_CMD_RNR;
			break;
		case 0x9:
			cmd = LAPD_CMD_REJ;
			break;
		default:
			LOGP(DMI, LOGL_ERROR, "unknown LAPD S cmd %x\n", data[2]);
			return NULL;
		};
	} else if ((data[2] & 3) == 3) {
		typ = LAPD_TYPE_U;
		pf = (data[2] >> 4) & 1;
		int val = data[2] & ~(1 << 4);
		switch (val) {
		case 0x6f:
			cmd = LAPD_CMD_SABME;
			break;
		case 0x0f:
			cmd = LAPD_CMD_DM;
			break;
		case 0x03:
			cmd = LAPD_CMD_UI;
			break;
		case 0x43:
			cmd = LAPD_CMD_DISC;
			break;
		case 0x63:
			cmd = LAPD_CMD_UA;
			break;
		case 0x87:
			cmd = LAPD_CMD_FRMR;
			break;
		case 0xaf:
			cmd = LAPD_CMD_XID;
			break;

		default:
			LOGP(DMI, LOGL_ERROR, "unknown U cmd %x "
			     "(pf %x data %x)\n", val, pf, data[2]);
			return NULL;
		};
	};

	contents = &data[4];
	if (typ == LAPD_TYPE_U)
		contents--;
	*ilen = len - (contents - data);

	if (tei == 127)
		lapd_tei_receive(li, contents, *ilen);

	teip = teip_from_tei(li, tei);

	DEBUGP(DMI, "<- %c %s sapi %x tei %3d cmd %x pf %x ns %3d nr %3d "
	     "ilen %d teip %p vs %d va %d vr %d len %d\n",
	     lapd_msg_types[typ], lapd_cmd_types[cmd], sapi, tei, command, pf,
	     ns, nr, *ilen, teip, teip ? teip->vs : -1, teip ? teip->va : -1,
	     teip ? teip->vr : -1, len);

	if (!teip) {
		LOGP(DMI, LOGL_NOTICE, "Unknown TEI %u\n", tei);
		return NULL;
	}

	switch (cmd) {
	case LAPD_CMD_I:
		if (ns != teip->vr) {
			DEBUGP(DMI, "ns %d != vr %d\n", ns, teip->vr);
			if (ns == ((teip->vr - 1) & 0x7f)) {
				DEBUGP(DMI, "DOUBLE FRAME, ignoring\n");
				cmd = 0;	// ignore
			} else {
				assert(0);
			};
		} else {
			//printf("IN SEQUENCE\n");
			teip->vr = (ns + 1) & 0x7f;	// FIXME: hack!
		};

		break;
	case LAPD_CMD_UI:
		break;
	case LAPD_CMD_SABME:
		teip->vs = 0;
		teip->vr = 0;
		teip->va = 0;

		// ua
		resp[l++] = data[0];
		resp[l++] = (tei << 1) | 1;
		resp[l++] = 0x73;
		li->transmit_cb(resp, l, li->cbdata);
		if (teip->state != LAPD_TEI_ACTIVE) {
			if (teip->state == LAPD_TEI_ASSIGNED) {
				lapd_tei_set_state(teip,
						   LAPD_TEI_ACTIVE);
				//printf("ASSIGNED and ACTIVE\n");
			} else {
#if 0
				DEBUGP(DMI, "rr in strange state, send rej\n");

				// rej
				resp[l++] = (teip-> sapi << 2) | (li->network_side ? 0 : 2);
				resp[l++] = (tei << 1) | 1;
				resp[l++] = 0x09;	//rej
				resp[l++] = ((teip->vr + 1) << 1) | 0;
				li->transmit_cb(resp, l, li->cbdata);
				pf = 0;	// dont reply
#endif
			};
		};

		*prim = LAPD_MPH_ACTIVATE_IND;
		break;
	case LAPD_CMD_UA:
		teip->vs = 0;
		teip->vr = 0;
		teip->va = 0;
		lapd_tei_set_state(teip, LAPD_TEI_ACTIVE);
		*prim = LAPD_MPH_ACTIVATE_IND;
		break;
	case LAPD_CMD_RR:
		teip->va = (nr & 0x7f);
#if 0
		if (teip->state != LAPD_TEI_ACTIVE) {
			if (teip->state == LAPD_TEI_ASSIGNED) {
				lapd_tei_set_state(teip, LAPD_TEI_ACTIVE);
				*prim = LAPD_MPH_ACTIVATE_IND;
				//printf("ASSIGNED and ACTIVE\n");
			} else {
#if 0
				DEBUGP(DMI, "rr in strange " "state, send rej\n");

				// rej
				resp[l++] = (teip-> sapi << 2) | (li->network_side ? 0 : 2);
				resp[l++] = (tei << 1) | 1;
				resp[l++] = 0x09;	//rej
				resp[l++] =
				    ((teip->vr + 1) << 1) | 0;
				li->transmit_cb(resp, l, li->cbdata);
				pf = 0;	// dont reply
#endif
			};
		};
#endif
		if (pf) {
			// interrogating us, send rr
			resp[l++] = data[0];
			resp[l++] = (tei << 1) | 1;
			resp[l++] = 0x01;	// rr
			resp[l++] = (LAPD_NR(teip) << 1) | (data[3] & 1);	// pf bit from req

			li->transmit_cb(resp, l, li->cbdata);

		};
		break;
	case LAPD_CMD_FRMR:
		// frame reject
#if 0
		if (teip->state == LAPD_TEI_ACTIVE)
			*prim = LAPD_MPH_DEACTIVATE_IND;
		lapd_tei_set_state(teip, LAPD_TEI_ASSIGNED);
#endif
		LOGP(DMI, LOGL_NOTICE, "frame reject, ignoring\n");
		break;
	case LAPD_CMD_DISC:
		// disconnect
		resp[l++] = data[0];
		resp[l++] = (tei << 1) | 1;
		resp[l++] = 0x73;
		li->transmit_cb(resp, l, li->cbdata);
		lapd_tei_set_state(teip, LAPD_TEI_NONE);
		break;
	default:
		LOGP(DMI, LOGL_NOTICE, "unknown cmd for tei %d (cmd %x)\n",
		     tei, cmd);
		break;
	}

	if (typ == LAPD_TYPE_I) {
		/* send rr
		 * Thu Jan 22 19:17:13 2009 <4000> sangoma.c:340 read  (62/25)   4: fa 33 01 0a 
		 * lapd <- S RR sapi 3e tei  25 cmd 0 pf 0 ns  -1 nr   5 ilen 0 teip 0x613800 vs 7 va 5 vr 2 len 4
		 */

		/* interrogating us, send rr */
		DEBUGP(DMI, "Sending RR response\n");
		resp[l++] = data[0];
		resp[l++] = (tei << 1) | 1;
		resp[l++] = 0x01;	// rr
		resp[l++] = (LAPD_NR(teip) << 1) | (data[3] & 1);	// pf bit from req

		li->transmit_cb(resp, l, li->cbdata);

		if (cmd != 0) {
			*prim = LAPD_DL_DATA_IND;
			return contents;
		}
	} else if (tei != 127 && typ == LAPD_TYPE_U && cmd == LAPD_CMD_UI) {
		*prim = LAPD_DL_UNITDATA_IND;
		return contents;
	}

	return NULL;
};

int lapd_send_sabm(struct lapd_instance *li, uint8_t tei, uint8_t sapi)
{
	struct msgb *msg = msgb_alloc_headroom(1024, 128, "LAPD SABM");
	if (!msg)
		return -ENOMEM;

	DEBUGP(DMI, "Sending SABM for TEI=%u, SAPI=%u\n", tei, sapi);

	/* make sure we know the TEI at the time the response comes in */
	if (!teip_from_tei(li, tei))
		lapd_tei_alloc(li, tei);

	msgb_put_u8(msg, (sapi << 2) | (li->network_side ? 2 : 0));
	msgb_put_u8(msg, (tei << 1) | 1);
	msgb_put_u8(msg, 0x7F);

	li->transmit_cb(msg->data, msg->len, li->cbdata);

	msgb_free(msg);

	return 0;
}

void lapd_transmit(struct lapd_instance *li, uint8_t tei, uint8_t sapi,
		   uint8_t *data, unsigned int len)
{
	//printf("lapd_transmit %d, %d\n", tei, len);
	//hexdump(data, len);
	struct lapd_tei *teip = teip_from_tei(li, tei);

	if (!teip) {
		LOGP(DMI, LOGL_ERROR, "Cannot transmit on non-existing "
		     "TEI %u\n", tei);
		return;
	}

	/* prepend stuff */
	uint8_t buf[10000];
	memset(buf, 0, sizeof(buf));
	memmove(buf + 4, data, len);
	len += 4;

	buf[0] = (sapi << 2) | (li->network_side ? 2 : 0);
	buf[1] = (tei << 1) | 1;
	buf[2] = (LAPD_NS(teip) << 1);
	buf[3] = (LAPD_NR(teip) << 1) | 0;

	teip->vs = (teip->vs + 1) & 0x7f;

	li->transmit_cb(buf, len, li->cbdata);
};

struct lapd_instance *lapd_instance_alloc(int network_side,
					  void (*tx_cb)(uint8_t *data, int len,
							void *cbdata), void *cbdata)
{
	struct lapd_instance *li;

	li = talloc_zero(NULL, struct lapd_instance);
	if (!li)
		return NULL;

	li->transmit_cb = tx_cb;
	li->cbdata = cbdata;
	li->network_side = network_side;
	INIT_LLIST_HEAD(&li->tei_list);

	return li;
}
