/* LAPD core implementation */

/* (C) 2010-2011 by Harald Welte <laforge@gnumonks.org>
 * (C) 2010-2011 by Andreas Eversberg <jolly@eversberg.eu>
 *
 * 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.
 *
 */

/*! \addtogroup lapd
 *  @{
 */

/*! \file lapd_core.c */

/*!
 * Notes on Buffering: rcv_buffer, tx_queue, tx_hist, send_buffer, send_queue
 *
 * RX data is stored in the rcv_buffer (pointer). If the message is complete, it
 * is removed from rcv_buffer pointer and forwarded to L3. If the RX data is
 * received while there is an incomplete rcv_buffer, it is appended to it.
 *
 * TX data is stored in the send_queue first. When transmitting a frame,
 * the first message in the send_queue is moved to the send_buffer. There it
 * resides until all fragments are acknowledged. Fragments to be sent by I
 * frames are stored in the tx_hist buffer for resend, if required. Also the
 * current fragment is copied into the tx_queue. There it resides until it is
 * forwarded to layer 1.
 *
 * In case we have SAPI 0, we only have a window size of 1, so the unack-
 * nowledged message resides always in the send_buffer. In case of a suspend,
 * it can be written back to the first position of the send_queue.
 *
 * The layer 1 normally sends a PH-READY-TO-SEND. But because we use
 * asynchronous transfer between layer 1 and layer 2 (serial link), we must
 * send a frame before layer 1 reaches the right timeslot to send it. So we
 * move the tx_queue to layer 1 when there is not already a pending frame, and
 * wait until acknowledge after the frame has been sent. If we receive an
 * acknowledge, we can send the next frame from the buffer, if any.
 *
 * The moving of tx_queue to layer 1 may also trigger T200, if desired. Also it
 * will trigger next I frame, if possible.
 *
 * T203 is optional. It will be stated when entering MF EST state. It will also
 * be started when I or S frame is received in that state . It will be
 * restarted in the lapd_acknowledge() function, in case outstanding frames
 * will not trigger T200. It will be stoped, when T200 is started in MF EST
 * state. It will also be stoped when leaving MF EST state.
 *
 */

/* Enable this to test content resolution on network side:
 * - The first SABM is received, UA is dropped.
 * - The phone repeats SABM, but it's content is wrong, so it is ignored
 * - The phone repeats SABM again, content is right, so UA is sent.
 */
//#define TEST_CONTENT_RESOLUTION_NETWORK

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>

#include <osmocom/core/logging.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/talloc.h>
#include <osmocom/gsm/lapd_core.h>

/* TS 04.06 Table 4 / Section 3.8.1 */
#define LAPD_U_SABM	0x7
#define LAPD_U_SABME	0xf
#define LAPD_U_DM	0x3
#define LAPD_U_UI	0x0
#define LAPD_U_DISC	0x8
#define LAPD_U_UA	0xC
#define LAPD_U_FRMR	0x11

#define LAPD_S_RR	0x0
#define LAPD_S_RNR	0x1
#define LAPD_S_REJ	0x2

#define CR_USER2NET_CMD		0
#define CR_USER2NET_RESP	1
#define CR_NET2USER_CMD		1
#define CR_NET2USER_RESP	0

#define LAPD_HEADROOM	56

#define SBIT(a) (1 << a)
#define ALL_STATES 0xffffffff

static void lapd_t200_cb(void *data);
static void lapd_t203_cb(void *data);
static int lapd_send_i(struct lapd_msg_ctx *lctx, int line);
static int lapd_est_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx);

/* UTILITY FUNCTIONS */

struct msgb *lapd_msgb_alloc(int length, const char *name)
{
	/* adding space for padding, FIXME: add as an option */
	if (length < 21)
		length = 21;
	return msgb_alloc_headroom(length + LAPD_HEADROOM, LAPD_HEADROOM, name);
}

static inline uint8_t do_mod(uint8_t x, uint8_t m)
{
	return x & (m - 1);
}

static inline uint8_t inc_mod(uint8_t x, uint8_t m)
{
	return (x + 1) & (m - 1);
}

static inline uint8_t add_mod(uint8_t x, uint8_t y, uint8_t m)
{
	return (x + y) & (m - 1);
}

static inline uint8_t sub_mod(uint8_t x, uint8_t y, uint8_t m)
{
	return (x - y) & (m - 1); /* handle negative results correctly */
}

static void lapd_dl_flush_send(struct lapd_datalink *dl)
{
	struct msgb *msg;

	/* Flush send-queue */
	while ((msg = msgb_dequeue(&dl->send_queue)))
		msgb_free(msg);

	/* Clear send-buffer */
	msgb_free(dl->send_buffer);
	dl->send_buffer = NULL;
}

static void lapd_dl_flush_hist(struct lapd_datalink *dl)
{
	unsigned int i;

	if (!dl->range_hist || !dl->tx_hist)
		return;

	for (i = 0; i < dl->range_hist; i++) {
		if (dl->tx_hist[i].msg) {
			msgb_free(dl->tx_hist[i].msg);
			dl->tx_hist[i].msg = NULL;
		}
	}
}

static void lapd_dl_flush_tx(struct lapd_datalink *dl)
{
	struct msgb *msg;

	while ((msg = msgb_dequeue(&dl->tx_queue)))
		msgb_free(msg);
	lapd_dl_flush_hist(dl);
}

/* Figure B.2/Q.921 */
const char *lapd_state_names[] = {
	"LAPD_STATE_NULL",
	"LAPD_STATE_TEI_UNASS",
	"LAPD_STATE_ASS_TEI_WAIT",
	"LAPD_STATE_EST_TEI_WAIT",
	"LAPD_STATE_IDLE",
	"LAPD_STATE_SABM_SENT",
	"LAPD_STATE_DISC_SENT",
	"LAPD_STATE_MF_EST",
	"LAPD_STATE_TIMER_RECOV",

};

static void lapd_start_t200(struct lapd_datalink *dl)
{
	if (osmo_timer_pending(&dl->t200))
		return;
	LOGP(DLLAPD, LOGL_INFO, "start T200\n");
	osmo_timer_schedule(&dl->t200, dl->t200_sec, dl->t200_usec);
}

static void lapd_start_t203(struct lapd_datalink *dl)
{
	if (osmo_timer_pending(&dl->t203))
		return;
	LOGP(DLLAPD, LOGL_INFO, "start T203\n");
	osmo_timer_schedule(&dl->t203, dl->t203_sec, dl->t203_usec);
}

static void lapd_stop_t200(struct lapd_datalink *dl)
{
	if (!osmo_timer_pending(&dl->t200))
		return;
	LOGP(DLLAPD, LOGL_INFO, "stop T200\n");
	osmo_timer_del(&dl->t200);
}

static void lapd_stop_t203(struct lapd_datalink *dl)
{
	if (!osmo_timer_pending(&dl->t203))
		return;
	LOGP(DLLAPD, LOGL_INFO, "stop T203\n");
	osmo_timer_del(&dl->t203);
}

static void lapd_dl_newstate(struct lapd_datalink *dl, uint32_t state)
{
	LOGP(DLLAPD, LOGL_INFO, "new state %s -> %s\n",
		lapd_state_names[dl->state], lapd_state_names[state]);

	if (state != LAPD_STATE_MF_EST && dl->state == LAPD_STATE_MF_EST) {
		/* stop T203 on leaving MF EST state, if running */
		lapd_stop_t203(dl);
		/* remove content res. (network side) on leaving MF EST state */
		msgb_free(dl->cont_res);
		dl->cont_res = NULL;
	}

	/* start T203 on entering MF EST state, if enabled */
	if ((dl->t203_sec || dl->t203_usec)
	 && state == LAPD_STATE_MF_EST && dl->state != LAPD_STATE_MF_EST)
		lapd_start_t203(dl);

	dl->state = state;
}

static void *tall_lapd_ctx = NULL;

/* init datalink instance and allocate history */
void lapd_dl_init(struct lapd_datalink *dl, uint8_t k, uint8_t v_range,
	int maxf)
{
	int m;

	memset(dl, 0, sizeof(*dl));
	INIT_LLIST_HEAD(&dl->send_queue);
	INIT_LLIST_HEAD(&dl->tx_queue);
	dl->reestablish = 1;
	dl->n200_est_rel = 3;
	dl->n200 = 3;
	dl->t200_sec = 1;
	dl->t200_usec = 0;
	dl->t200.data = dl;
	dl->t200.cb = &lapd_t200_cb;
	dl->t203_sec = 10;
	dl->t203_usec = 0;
	dl->t203.data = dl;
	dl->t203.cb = &lapd_t203_cb;
	dl->maxf = maxf;
	if (k > v_range - 1)
		k = v_range - 1;
	dl->k = k;
	dl->v_range = v_range;

	/* Calculate modulo for history array:
	 * - The history range must be at least k+1.
	 * - The history range must be 2^x, where x is as low as possible.
	 */
	k++;
	for (m = 0x80; m; m >>= 1) {
		if ((m & k)) {
			if (k > m)
				m <<= 1;
			dl->range_hist = m;
			break;
		}
	}

	LOGP(DLLAPD, LOGL_INFO, "Init DL layer: sequence range = %d, k = %d, "
		"history range = %d\n", dl->v_range, dl->k, dl->range_hist);

	lapd_dl_newstate(dl, LAPD_STATE_IDLE);

	if (!tall_lapd_ctx)
		tall_lapd_ctx = talloc_named_const(NULL, 1, "lapd context");
	dl->tx_hist = talloc_zero_array(tall_lapd_ctx,
					struct lapd_history, dl->range_hist);
}

/* reset to IDLE state */
void lapd_dl_reset(struct lapd_datalink *dl)
{
	if (dl->state == LAPD_STATE_IDLE)
		return;
	LOGP(DLLAPD, LOGL_INFO, "Resetting LAPDm instance\n");
	/* enter idle state (and remove eventual cont_res) */
	lapd_dl_newstate(dl, LAPD_STATE_IDLE);
	/* flush buffer */
	lapd_dl_flush_tx(dl);
	lapd_dl_flush_send(dl);
	/* Discard partly received L3 message */
	msgb_free(dl->rcv_buffer);
	dl->rcv_buffer = NULL;
	/* stop Timers */
	lapd_stop_t200(dl);
	lapd_stop_t203(dl);
}

/* reset and de-allocate history buffer */
void lapd_dl_exit(struct lapd_datalink *dl)
{
	/* free all ressources except history buffer */
	lapd_dl_reset(dl);
	/* free history buffer list */
	talloc_free(dl->tx_hist);
	dl->tx_hist = NULL;
}

/*! \brief Set the \ref lapdm_mode of a LAPDm entity */
int lapd_set_mode(struct lapd_datalink *dl, enum lapd_mode mode)
{
	switch (mode) {
	case LAPD_MODE_USER:
		dl->cr.loc2rem.cmd = CR_USER2NET_CMD;
		dl->cr.loc2rem.resp = CR_USER2NET_RESP;
		dl->cr.rem2loc.cmd = CR_NET2USER_CMD;
		dl->cr.rem2loc.resp = CR_NET2USER_RESP;
		break;
	case LAPD_MODE_NETWORK:
		dl->cr.loc2rem.cmd = CR_NET2USER_CMD;
		dl->cr.loc2rem.resp = CR_NET2USER_RESP;
		dl->cr.rem2loc.cmd = CR_USER2NET_CMD;
		dl->cr.rem2loc.resp = CR_USER2NET_RESP;
		break;
	default:
		return -EINVAL;
	}
	dl->mode = mode;

	return 0;
}

/* send DL message with optional msgb */
static int send_dl_l3(uint8_t prim, uint8_t op, struct lapd_msg_ctx *lctx,
	struct msgb *msg)
{
	struct lapd_datalink *dl = lctx->dl;
	struct osmo_dlsap_prim dp;

	osmo_prim_init(&dp.oph, 0, prim, op, msg);
	return dl->send_dlsap(&dp, lctx);
}

/* send simple DL message */
static inline int send_dl_simple(uint8_t prim, uint8_t op,
	struct lapd_msg_ctx *lctx)
{
	struct msgb *msg = lapd_msgb_alloc(0, "DUMMY");

	return send_dl_l3(prim, op, lctx, msg);
}

/* send MDL-ERROR INDICATION */
static int mdl_error(uint8_t cause, struct lapd_msg_ctx *lctx)
{
	struct lapd_datalink *dl = lctx->dl;
	struct osmo_dlsap_prim dp;

	LOGP(DLLAPD, LOGL_NOTICE, "sending MDL-ERROR-IND cause %d\n",
		cause);
	osmo_prim_init(&dp.oph, 0, PRIM_MDL_ERROR, PRIM_OP_INDICATION, NULL);
	dp.u.error_ind.cause = cause;
	return dl->send_dlsap(&dp, lctx);
}

/* send UA response */
static int lapd_send_ua(struct lapd_msg_ctx *lctx, uint8_t len, uint8_t *data)
{
	struct msgb *msg = lapd_msgb_alloc(len, "LAPD UA");
	struct lapd_msg_ctx nctx;
	struct lapd_datalink *dl = lctx->dl;

	memcpy(&nctx, lctx, sizeof(nctx));
	msg->l3h = msgb_put(msg, len);
	if (len)
		memcpy(msg->l3h, data, len);
	/* keep nctx.ldp */
	/* keep nctx.sapi */
	/* keep nctx.tei */
	nctx.cr = dl->cr.loc2rem.resp;
	nctx.format = LAPD_FORM_U;
	nctx.s_u = LAPD_U_UA;
	/* keep nctx.p_f */
	nctx.length = len;
	nctx.more = 0;

	return dl->send_ph_data_req(&nctx, msg);
}

/* send DM response */
static int lapd_send_dm(struct lapd_msg_ctx *lctx)
{
	struct msgb *msg = lapd_msgb_alloc(0, "LAPD DM");
	struct lapd_msg_ctx nctx;
	struct lapd_datalink *dl = lctx->dl;

	memcpy(&nctx, lctx, sizeof(nctx));
	/* keep nctx.ldp */
	/* keep nctx.sapi */
	/* keep nctx.tei */
	nctx.cr = dl->cr.loc2rem.resp;
	nctx.format = LAPD_FORM_U;
	nctx.s_u = LAPD_U_DM;
	/* keep nctx.p_f */
	nctx.length = 0;
	nctx.more = 0;

	return dl->send_ph_data_req(&nctx, msg);
}

/* send RR response / command */
static int lapd_send_rr(struct lapd_msg_ctx *lctx, uint8_t f_bit, uint8_t cmd)
{
	struct msgb *msg = lapd_msgb_alloc(0, "LAPD RR");
	struct lapd_msg_ctx nctx;
	struct lapd_datalink *dl = lctx->dl;

	memcpy(&nctx, lctx, sizeof(nctx));
	/* keep nctx.ldp */
	/* keep nctx.sapi */
	/* keep nctx.tei */
	nctx.cr = (cmd) ? dl->cr.loc2rem.cmd : dl->cr.loc2rem.resp;
	nctx.format = LAPD_FORM_S;
	nctx.s_u = LAPD_S_RR;
	nctx.p_f = f_bit;
	nctx.n_recv = dl->v_recv;
	nctx.length = 0;
	nctx.more = 0;

	return dl->send_ph_data_req(&nctx, msg);
}

/* send RNR response / command */
static int lapd_send_rnr(struct lapd_msg_ctx *lctx, uint8_t f_bit, uint8_t cmd)
{
	struct msgb *msg = lapd_msgb_alloc(0, "LAPD RNR");
	struct lapd_msg_ctx nctx;
	struct lapd_datalink *dl = lctx->dl;

	memcpy(&nctx, lctx, sizeof(nctx));
	/* keep nctx.ldp */
	/* keep nctx.sapi */
	/* keep nctx.tei */
	nctx.cr = (cmd) ? dl->cr.loc2rem.cmd : dl->cr.loc2rem.resp;
	nctx.format = LAPD_FORM_S;
	nctx.s_u = LAPD_S_RNR;
	nctx.p_f = f_bit;
	nctx.n_recv = dl->v_recv;
	nctx.length = 0;
	nctx.more = 0;

	return dl->send_ph_data_req(&nctx, msg);
}

/* send REJ response */
static int lapd_send_rej(struct lapd_msg_ctx *lctx, uint8_t f_bit)
{
	struct msgb *msg = lapd_msgb_alloc(0, "LAPD REJ");
	struct lapd_msg_ctx nctx;
	struct lapd_datalink *dl = lctx->dl;

	memcpy(&nctx, lctx, sizeof(nctx));
	/* keep nctx.ldp */
	/* keep nctx.sapi */
	/* keep nctx.tei */
	nctx.cr = dl->cr.loc2rem.resp;
	nctx.format = LAPD_FORM_S;
	nctx.s_u = LAPD_S_REJ;
	nctx.p_f = f_bit;
	nctx.n_recv = dl->v_recv;
	nctx.length = 0;
	nctx.more = 0;

	return dl->send_ph_data_req(&nctx, msg);
}

/* resend SABM or DISC message */
static int lapd_send_resend(struct lapd_datalink *dl)
{
	struct msgb *msg;
	uint8_t h = do_mod(dl->v_send, dl->range_hist);
	int length = dl->tx_hist[h].msg->len;
	struct lapd_msg_ctx nctx;

	/* assemble message */
	memcpy(&nctx, &dl->lctx, sizeof(nctx));
	/* keep nctx.ldp */
	/* keep nctx.sapi */
	/* keep nctx.tei */
	nctx.cr = dl->cr.loc2rem.cmd;
	nctx.format = LAPD_FORM_U;
	if (dl->state == LAPD_STATE_SABM_SENT)
		nctx.s_u = (dl->use_sabme) ? LAPD_U_SABME : LAPD_U_SABM;
	else
		nctx.s_u = LAPD_U_DISC;
	nctx.p_f = 1;
	nctx.length = length;
	nctx.more = 0;

	/* Resend SABM/DISC from tx_hist */
	msg = lapd_msgb_alloc(length, "LAPD resend");
	msg->l3h = msgb_put(msg, length);
	if (length)
		memcpy(msg->l3h, dl->tx_hist[h].msg->data, length);

	return dl->send_ph_data_req(&nctx, msg);
}

/* reestablish link */
static int lapd_reestablish(struct lapd_datalink *dl)
{
	struct osmo_dlsap_prim dp;
	struct msgb *msg;

	msg = lapd_msgb_alloc(0, "DUMMY");
	osmo_prim_init(&dp.oph, 0, PRIM_DL_EST, PRIM_OP_REQUEST, msg);
	
	return lapd_est_req(&dp, &dl->lctx);
}

/* Timer callback on T200 expiry */
static void lapd_t200_cb(void *data)
{
	struct lapd_datalink *dl = data;

	LOGP(DLLAPD, LOGL_INFO, "Timeout T200 (%p) state=%d\n", dl,
		(int) dl->state);

	switch (dl->state) {
	case LAPD_STATE_SABM_SENT:
		/* 5.4.1.3 */
		if (dl->retrans_ctr + 1 >= dl->n200_est_rel + 1) {
			/* send RELEASE INDICATION to L3 */
			send_dl_simple(PRIM_DL_REL, PRIM_OP_INDICATION,
				&dl->lctx);
			/* send MDL ERROR INIDCATION to L3 */
			mdl_error(MDL_CAUSE_T200_EXPIRED, &dl->lctx);
			/* flush tx and send buffers */
			lapd_dl_flush_tx(dl);
			lapd_dl_flush_send(dl);
			/* go back to idle state */
			lapd_dl_newstate(dl, LAPD_STATE_IDLE);
			/* NOTE: we must not change any other states or buffers
			 * and queues, since we may reconnect after handover
			 * failure. the buffered messages is replaced there */
			break;
		}
		/* retransmit SABM command */
		lapd_send_resend(dl);
		/* increment re-transmission counter */
		dl->retrans_ctr++;
		/* restart T200 (PH-READY-TO-SEND) */
		lapd_start_t200(dl);
		break;
	case LAPD_STATE_DISC_SENT:
		/* 5.4.4.3 */
		if (dl->retrans_ctr + 1 >= dl->n200_est_rel + 1) {
			/* send RELEASE INDICATION to L3 */
			send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, &dl->lctx);
			/* send MDL ERROR INIDCATION to L3 */
			mdl_error(MDL_CAUSE_T200_EXPIRED, &dl->lctx);
			/* flush tx and send buffers */
			lapd_dl_flush_tx(dl);
			lapd_dl_flush_send(dl);
			/* go back to idle state */
			lapd_dl_newstate(dl, LAPD_STATE_IDLE);
			/* NOTE: we must not change any other states or buffers
			 * and queues, since we may reconnect after handover
			 * failure. the buffered messages is replaced there */
			break;
		}
		/* retransmit DISC command */
		lapd_send_resend(dl);
		/* increment re-transmission counter */
		dl->retrans_ctr++;
		/* restart T200 (PH-READY-TO-SEND) */
		lapd_start_t200(dl);
		break;
	case LAPD_STATE_MF_EST:
		/* 5.5.7 */
		dl->retrans_ctr = 0;
		lapd_dl_newstate(dl, LAPD_STATE_TIMER_RECOV);
		/* fall through */
	case LAPD_STATE_TIMER_RECOV:
		dl->retrans_ctr++;
		if (dl->retrans_ctr < dl->n200) {
			uint8_t vs = sub_mod(dl->v_send, 1, dl->v_range);
			uint8_t h = do_mod(vs, dl->range_hist);
			/* retransmit I frame (V_s-1) with P=1, if any */
			if (dl->tx_hist[h].msg) {
				struct msgb *msg;
				int length = dl->tx_hist[h].msg->len;
				struct lapd_msg_ctx nctx;

				LOGP(DLLAPD, LOGL_INFO, "retransmit last frame"
					" V(S)=%d\n", vs);
				/* Create I frame (segment) from tx_hist */
				memcpy(&nctx, &dl->lctx, sizeof(nctx));
				/* keep nctx.ldp */
				/* keep nctx.sapi */
				/* keep nctx.tei */
				nctx.cr = dl->cr.loc2rem.cmd;
				nctx.format = LAPD_FORM_I;
				nctx.p_f = 1;
				nctx.n_send = vs;
				nctx.n_recv = dl->v_recv;
				nctx.length = length;
				nctx.more = dl->tx_hist[h].more;
				msg = lapd_msgb_alloc(length, "LAPD I resend");
				msg->l3h = msgb_put(msg, length);
				memcpy(msg->l3h, dl->tx_hist[h].msg->data,
					length);
				dl->send_ph_data_req(&nctx, msg);
			} else {
			/* OR send appropriate supervision frame with P=1 */
				if (!dl->own_busy && !dl->seq_err_cond) {
					lapd_send_rr(&dl->lctx, 1, 1);
					/* NOTE: In case of sequence error
					 * condition, the REJ frame has been
					 * transmitted when entering the
					 * condition, so it has not be done
					 * here
				 	 */
				} else if (dl->own_busy) {
					lapd_send_rnr(&dl->lctx, 1, 1);
				} else {
					LOGP(DLLAPD, LOGL_INFO, "unhandled, "
						"pls. fix\n");
				}
			}
			/* restart T200 (PH-READY-TO-SEND) */
			lapd_start_t200(dl);
		} else {
			/* send MDL ERROR INIDCATION to L3 */
			mdl_error(MDL_CAUSE_T200_EXPIRED, &dl->lctx);
			/* reestablish */
			if (!dl->reestablish)
				break;
			LOGP(DLLAPD, LOGL_NOTICE, "N200 reached, performing "
				"reestablishment.\n");
			lapd_reestablish(dl);
		}
		break;
	default:
		LOGP(DLLAPD, LOGL_INFO, "T200 expired in unexpected "
			"dl->state %d\n", (int) dl->state);
	}
}

/* Timer callback on T203 expiry */
static void lapd_t203_cb(void *data)
{
	struct lapd_datalink *dl = data;

	LOGP(DLLAPD, LOGL_INFO, "Timeout T203 (%p) state=%d\n", dl,
		(int) dl->state);

	if (dl->state != LAPD_STATE_MF_EST) {
		LOGP(DLLAPD, LOGL_ERROR, "T203 fired outside MF EST state, "
			"please fix!\n");
		return;
	}

	/* set retransmission counter to 0 */
	dl->retrans_ctr = 0;
	/* enter timer recovery state */
	lapd_dl_newstate(dl, LAPD_STATE_TIMER_RECOV);
	/* transmit a supervisory command with P bit set to 1 as follows: */
	if (!dl->own_busy) {
		LOGP(DLLAPD, LOGL_INFO, "transmit an RR poll command\n");
		/* Send RR with P=1 */
		lapd_send_rr(&dl->lctx, 1, 1);
	} else {
		LOGP(DLLAPD, LOGL_INFO, "transmit an RNR poll command\n");
		/* Send RNR with P=1 */
		lapd_send_rnr(&dl->lctx, 1, 1);
	}
	/* start T200 */
	lapd_start_t200(dl);
}

/* 5.5.3.1: Common function to acknowlege frames up to the given N(R) value */
static void lapd_acknowledge(struct lapd_msg_ctx *lctx)
{
	struct lapd_datalink *dl = lctx->dl;
	uint8_t nr = lctx->n_recv;
	int s = 0, rej = 0, t200_reset = 0;
	int i, h;

	/* supervisory frame ? */
	if (lctx->format == LAPD_FORM_S)
		s = 1;
	/* REJ frame ? */
	if (s && lctx->s_u == LAPD_S_REJ)
	 	rej = 1;

	/* Flush all transmit buffers of acknowledged frames */
	for (i = dl->v_ack; i != nr; i = inc_mod(i, dl->v_range)) {
		h = do_mod(i, dl->range_hist);
		if (dl->tx_hist[h].msg) {
			msgb_free(dl->tx_hist[h].msg);
			dl->tx_hist[h].msg = NULL;
			LOGP(DLLAPD, LOGL_INFO, "ack frame %d\n", i);
		}
	}

	if (dl->state != LAPD_STATE_TIMER_RECOV) {
		/* When not in the timer recovery condition, the data
		 * link layer entity shall reset the timer T200 on
		 * receipt of a valid I frame with N(R) higher than V(A),
		 * or an REJ with an N(R) equal to V(A). */
		if ((!rej && nr != dl->v_ack)
		 || (rej && nr == dl->v_ack)) {
		 	t200_reset = 1;
			lapd_stop_t200(dl);
			/* 5.5.3.1 Note 1 + 2 imply timer recovery cond. */
		}
		/* 5.7.4: N(R) sequence error
		 * N(R) is called valid, if and only if
		 * (N(R)-V(A)) mod 8 <= (V(S)-V(A)) mod 8.
		 */
		if (sub_mod(nr, dl->v_ack, dl->v_range)
				> sub_mod(dl->v_send, dl->v_ack, dl->v_range)) {
			LOGP(DLLAPD, LOGL_NOTICE, "N(R) sequence error\n");
			mdl_error(MDL_CAUSE_SEQ_ERR, lctx);
		}
	}

	/* V(A) shall be set to the value of N(R) */
	dl->v_ack = nr;

	/* If T200 has been stopped by the receipt of an I, RR or RNR frame,
	 * and if there are outstanding I frames, restart T200 */
	if (t200_reset && !rej) {
		if (dl->tx_hist[sub_mod(dl->v_send, 1, dl->range_hist)].msg) {
			LOGP(DLLAPD, LOGL_INFO, "start T200, due to unacked I "
				"frame(s)\n");
			lapd_start_t200(dl);
		}
	}

	/* This also does a restart, when I or S frame is received */

	/* Stop T203, if running */
	lapd_stop_t203(dl);
	/* Start T203, if T200 is not running in MF EST state, if enabled */
	if (!osmo_timer_pending(&dl->t200)
	 && (dl->t203_sec || dl->t203_usec)
	 && (dl->state == LAPD_STATE_MF_EST)) {
		lapd_start_t203(dl);
	}
}

/* L1 -> L2 */

/* Receive a LAPD U (Unnumbered) message from L1 */
static int lapd_rx_u(struct msgb *msg, struct lapd_msg_ctx *lctx)
{
	struct lapd_datalink *dl = lctx->dl;
	int length = lctx->length;
	int rc = 0;
	uint8_t prim, op;

	switch (lctx->s_u) {
	case LAPD_U_SABM:
	case LAPD_U_SABME:
		prim = PRIM_DL_EST;
		op = PRIM_OP_INDICATION;

		LOGP(DLLAPD, LOGL_INFO, "SABM(E) received in state %s\n",
			lapd_state_names[dl->state]);
		/* 5.7.1 */
		dl->seq_err_cond = 0;
		/* G.2.2 Wrong value of the C/R bit */
		if (lctx->cr == dl->cr.rem2loc.resp) {
			LOGP(DLLAPD, LOGL_ERROR, "SABM response error\n");
			msgb_free(msg);
			mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
			return -EINVAL;
		}

		/* G.4.5 If SABM is received with L>N201 or with M bit
		 * set, AN MDL-ERROR-INDICATION is sent to MM.
		 */
		if (lctx->more || length > lctx->n201) {
			LOGP(DLLAPD, LOGL_ERROR, "SABM too large error\n");
			msgb_free(msg);
			mdl_error(MDL_CAUSE_UFRM_INC_PARAM, lctx);
			return -EIO;
		}

		switch (dl->state) {
		case LAPD_STATE_IDLE:
			break;
		case LAPD_STATE_MF_EST:
			LOGP(DLLAPD, LOGL_INFO, "SABM command, multiple "
				"frame established state\n");
			/* If link is lost on the remote side, we start over
			 * and send DL-ESTABLISH indication again. */
			/* Additionally, continue in case of content resoltion
			 * (GSM network). This happens, if the mobile has not
			 * yet received UA or another mobile (collision) tries
			 * to establish connection. The mobile must receive
			 * UA again. */
			/* 5.4.2.1 */
			if (!length) {
				/* If no content resolution, this is a
				 * re-establishment. */
				LOGP(DLLAPD, LOGL_INFO,
					"Remote reestablish\n");
				break;
			}
			if (!dl->cont_res) {
				LOGP(DLLAPD, LOGL_INFO, "SABM command not "
						"allowed in this state\n");
				mdl_error(MDL_CAUSE_SABM_MF, lctx);
				msgb_free(msg);
				return 0;
			}
			/* Ignore SABM if content differs from first SABM. */
			if (dl->mode == LAPD_MODE_NETWORK && length) {
#ifdef TEST_CONTENT_RESOLUTION_NETWORK
				dl->cont_res->data[0] ^= 0x01;
#endif
				if (memcmp(dl->cont_res->data, msg->data,
								length)) {
					LOGP(DLLAPD, LOGL_INFO, "Another SABM "
						"with diffrent content - "
						"ignoring!\n");
					msgb_free(msg);
					return 0;
				}
			}
			/* send UA again */
			lapd_send_ua(lctx, length, msg->l3h);
			msgb_free(msg);
			return 0;
		case LAPD_STATE_DISC_SENT:
			/* 5.4.6.2 send DM with F=P */
			lapd_send_dm(lctx);
			/* stop Timer T200 */
			lapd_stop_t200(dl);
			msgb_free(msg);
			return send_dl_simple(prim, op, lctx);
		default:
			/* collision: Send UA, but still wait for rx UA, then
			 * change to MF_EST state.
			 */
			/* check for contention resoultion */
			if (dl->tx_hist[0].msg && dl->tx_hist[0].msg->len) {
				LOGP(DLLAPD, LOGL_NOTICE, "SABM not allowed "
					"during contention resolution\n");
				mdl_error(MDL_CAUSE_SABM_INFO_NOTALL, lctx);
			}
			lapd_send_ua(lctx, length, msg->l3h);
			msgb_free(msg);
			return 0;
		}
		/* save message context for further use */
		memcpy(&dl->lctx, lctx, sizeof(dl->lctx));
#ifndef TEST_CONTENT_RESOLUTION_NETWORK
		/* send UA response */
		lapd_send_ua(lctx, length, msg->l3h);
#endif
		/* set Vs, Vr and Va to 0 */
		dl->v_send = dl->v_recv = dl->v_ack = 0;
		/* clear tx_hist */
		lapd_dl_flush_hist(dl);
		/* enter multiple-frame-established state */
		lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
		/* store content resolution data on network side
		 * Note: cont_res will be removed when changing state again,
		 * so it must be allocated AFTER lapd_dl_newstate(). */
		if (dl->mode == LAPD_MODE_NETWORK && length) {
			dl->cont_res = lapd_msgb_alloc(length, "CONT RES");
			memcpy(msgb_put(dl->cont_res, length), msg->l3h,
				length);
			LOGP(DLLAPD, LOGL_NOTICE, "Store content res.\n");
		}
		/* send notification to L3 */
		if (length == 0) {
			/* 5.4.1.2 Normal establishment procedures */
			rc = send_dl_simple(prim, op, lctx);
			msgb_free(msg);
		} else {
			/* 5.4.1.4 Contention resolution establishment */
			msgb_trim(msg, length);
			rc = send_dl_l3(prim, op, lctx, msg);
		}
		break;
	case LAPD_U_DM:
		LOGP(DLLAPD, LOGL_INFO, "DM received in state %s\n",
			lapd_state_names[dl->state]);
		/* G.2.2 Wrong value of the C/R bit */
		if (lctx->cr == dl->cr.rem2loc.cmd) {
			LOGP(DLLAPD, LOGL_ERROR, "DM command error\n");
			msgb_free(msg);
			mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
			return -EINVAL;
		}
		if (!lctx->p_f) {
			/* 5.4.1.2 DM responses with the F bit set to "0"
			 * shall be ignored.
			 */
			msgb_free(msg);
			return 0;
		}
		switch (dl->state) {
		case LAPD_STATE_SABM_SENT:
			break;
		case LAPD_STATE_MF_EST:
			if (lctx->p_f) {
				LOGP(DLLAPD, LOGL_INFO, "unsolicited DM "
					"response\n");
				mdl_error(MDL_CAUSE_UNSOL_DM_RESP, lctx);
			} else {
				LOGP(DLLAPD, LOGL_INFO, "unsolicited DM "
					"response, multiple frame established "
					"state\n");
				mdl_error(MDL_CAUSE_UNSOL_DM_RESP_MF, lctx);
				/* reestablish */
				if (!dl->reestablish) {
					msgb_free(msg);
					return 0;
				}
				LOGP(DLLAPD, LOGL_NOTICE, "Performing "
					"reestablishment.\n");
				lapd_reestablish(dl);
			}
			msgb_free(msg);
			return 0;
		case LAPD_STATE_TIMER_RECOV:
			/* FP = 0 (DM is normal in case PF = 1) */
			if (!lctx->p_f) {
				LOGP(DLLAPD, LOGL_INFO, "unsolicited DM "
					"response, multiple frame established "
					"state\n");
				mdl_error(MDL_CAUSE_UNSOL_DM_RESP_MF, lctx);
				msgb_free(msg);
				/* reestablish */
				if (!dl->reestablish)
					return 0;
				LOGP(DLLAPD, LOGL_NOTICE, "Performing "
					"reestablishment.\n");
				return lapd_reestablish(dl);
			}
			break;
		case LAPD_STATE_DISC_SENT:
			/* stop Timer T200 */
			lapd_stop_t200(dl);
			/* go to idle state */
			lapd_dl_flush_tx(dl);
			lapd_dl_flush_send(dl);
			lapd_dl_newstate(dl, LAPD_STATE_IDLE);
			rc = send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, lctx);
			msgb_free(msg);
			return 0;
		case LAPD_STATE_IDLE:
			/* 5.4.5 all other frame types shall be discarded */
		default:
			LOGP(DLLAPD, LOGL_INFO, "unsolicited DM response! "
				"(discarding)\n");
			msgb_free(msg);
			return 0;
		}
		/* stop timer T200 */
		lapd_stop_t200(dl);
		/* go to idle state */
		lapd_dl_newstate(dl, LAPD_STATE_IDLE);
		rc = send_dl_simple(PRIM_DL_REL, PRIM_OP_INDICATION, lctx);
		msgb_free(msg);
		break;
	case LAPD_U_UI:
		LOGP(DLLAPD, LOGL_INFO, "UI received\n");
		/* G.2.2 Wrong value of the C/R bit */
		if (lctx->cr == dl->cr.rem2loc.resp) {
			LOGP(DLLAPD, LOGL_ERROR, "UI indicates response "
				"error\n");
			msgb_free(msg);
			mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
			return -EINVAL;
		}

		/* G.4.5 If UI is received with L>N201 or with M bit
		 * set, AN MDL-ERROR-INDICATION is sent to MM.
		 */
		if (length > lctx->n201 || lctx->more) {
			LOGP(DLLAPD, LOGL_ERROR, "UI too large error "
				"(%d > N201(%d) or M=%d)\n", length,
				lctx->n201, lctx->more);
			msgb_free(msg);
			mdl_error(MDL_CAUSE_UFRM_INC_PARAM, lctx);
			return -EIO;
		}

		/* do some length checks */
		if (length == 0) {
			/* 5.3.3 UI frames received with the length indicator
			 * set to "0" shall be ignored
			 */
			LOGP(DLLAPD, LOGL_INFO, "length=0 (discarding)\n");
			msgb_free(msg);
			return 0;
		}
		msgb_trim(msg, length);
		rc = send_dl_l3(PRIM_DL_UNIT_DATA, PRIM_OP_INDICATION, lctx,
				msg);
		break;
	case LAPD_U_DISC:
		prim = PRIM_DL_REL;
		op = PRIM_OP_INDICATION;

		LOGP(DLLAPD, LOGL_INFO, "DISC received in state %s\n",
			lapd_state_names[dl->state]);
		/* flush tx and send buffers */
		lapd_dl_flush_tx(dl);
		lapd_dl_flush_send(dl);
		/* 5.7.1 */
		dl->seq_err_cond = 0;
		/* G.2.2 Wrong value of the C/R bit */
		if (lctx->cr == dl->cr.rem2loc.resp) {
			LOGP(DLLAPD, LOGL_ERROR, "DISC response error\n");
			msgb_free(msg);
			mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
			return -EINVAL;
		}
		if (length > 0 || lctx->more) {
			/* G.4.4 If a DISC or DM frame is received with L>0 or
			 * with the M bit set to "1", an MDL-ERROR-INDICATION
			 * primitive with cause "U frame with incorrect
			 * parameters" is sent to the mobile management entity.
			 */
			LOGP(DLLAPD, LOGL_ERROR,
				"U frame iwth incorrect parameters ");
			msgb_free(msg);
			mdl_error(MDL_CAUSE_UFRM_INC_PARAM, lctx);
			return -EIO;
		}
		switch (dl->state) {
		case LAPD_STATE_IDLE:
			LOGP(DLLAPD, LOGL_INFO, "DISC in idle state\n");
			/* send DM with F=P */
			msgb_free(msg);
			return lapd_send_dm(lctx);
		case LAPD_STATE_SABM_SENT:
			LOGP(DLLAPD, LOGL_INFO, "DISC in SABM state\n");
			/* 5.4.6.2 send DM with F=P */
			lapd_send_dm(lctx);
			/* stop Timer T200 */
			lapd_stop_t200(dl);
			/* go to idle state */
			lapd_dl_newstate(dl, LAPD_STATE_IDLE);
			msgb_free(msg);
			return send_dl_simple(PRIM_DL_REL, PRIM_OP_INDICATION,
				lctx);
		case LAPD_STATE_MF_EST:
		case LAPD_STATE_TIMER_RECOV:
			LOGP(DLLAPD, LOGL_INFO, "DISC in est state\n");
			break;
		case LAPD_STATE_DISC_SENT:
			LOGP(DLLAPD, LOGL_INFO, "DISC in disc state\n");
			prim = PRIM_DL_REL;
			op = PRIM_OP_CONFIRM;
			break;
		default:
			lapd_send_ua(lctx, length, msg->l3h);
			msgb_free(msg);
			return 0;
		}
		/* send UA response */
		lapd_send_ua(lctx, length, msg->l3h);
		/* stop Timer T200 */
		lapd_stop_t200(dl);
		/* enter idle state, keep tx-buffer with UA response */
		lapd_dl_newstate(dl, LAPD_STATE_IDLE);
		/* send notification to L3 */
		rc = send_dl_simple(prim, op, lctx);
		msgb_free(msg);
		break;
	case LAPD_U_UA:
		LOGP(DLLAPD, LOGL_INFO, "UA received in state %s\n",
			lapd_state_names[dl->state]);
		/* G.2.2 Wrong value of the C/R bit */
		if (lctx->cr == dl->cr.rem2loc.cmd) {
			LOGP(DLLAPD, LOGL_ERROR, "UA indicates command "
				"error\n");
			msgb_free(msg);
			mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
			return -EINVAL;
		}

		/* G.4.5 If UA is received with L>N201 or with M bit
		 * set, AN MDL-ERROR-INDICATION is sent to MM.
		 */
		if (lctx->more || length > lctx->n201) {
			LOGP(DLLAPD, LOGL_ERROR, "UA too large error\n");
			msgb_free(msg);
			mdl_error(MDL_CAUSE_UFRM_INC_PARAM, lctx);
			return -EIO;
		}

		if (!lctx->p_f) {
			/* 5.4.1.2 A UA response with the F bit set to "0"
			 * shall be ignored.
			 */
			LOGP(DLLAPD, LOGL_INFO, "F=0 (discarding)\n");
			msgb_free(msg);
			return 0;
		}
		switch (dl->state) {
		case LAPD_STATE_SABM_SENT:
			break;
		case LAPD_STATE_MF_EST:
		case LAPD_STATE_TIMER_RECOV:
			LOGP(DLLAPD, LOGL_INFO, "unsolicited UA response! "
				"(discarding)\n");
			mdl_error(MDL_CAUSE_UNSOL_UA_RESP, lctx);
			msgb_free(msg);
			return 0;
		case LAPD_STATE_DISC_SENT:
			LOGP(DLLAPD, LOGL_INFO, "UA in disconnect state\n");
			/* stop Timer T200 */
			lapd_stop_t200(dl);
			/* go to idle state */
			lapd_dl_flush_tx(dl);
			lapd_dl_flush_send(dl);
			lapd_dl_newstate(dl, LAPD_STATE_IDLE);
			rc = send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, lctx);
			msgb_free(msg);
			return 0;
		case LAPD_STATE_IDLE:
			/* 5.4.5 all other frame types shall be discarded */
		default:
			LOGP(DLLAPD, LOGL_INFO, "unsolicited UA response! "
				"(discarding)\n");
			msgb_free(msg);
			return 0;
		}
		LOGP(DLLAPD, LOGL_INFO, "UA in SABM state\n");
		/* stop Timer T200 */
		lapd_stop_t200(dl);
		/* compare UA with SABME if contention resolution is applied */
		if (dl->tx_hist[0].msg->len) {
			if (length != (dl->tx_hist[0].msg->len)
			 || !!memcmp(dl->tx_hist[0].msg->data, msg->l3h,
			 					length)) {
				LOGP(DLLAPD, LOGL_INFO, "**** UA response "
					"mismatches ****\n");
				rc = send_dl_simple(PRIM_DL_REL,
					PRIM_OP_INDICATION, lctx);
				msgb_free(msg);
				/* go to idle state */
				lapd_dl_flush_tx(dl);
				lapd_dl_flush_send(dl);
				lapd_dl_newstate(dl, LAPD_STATE_IDLE);
				return 0;
			}
		}
		/* set Vs, Vr and Va to 0 */
		dl->v_send = dl->v_recv = dl->v_ack = 0;
		/* clear tx_hist */
		lapd_dl_flush_hist(dl);
		/* enter multiple-frame-established state */
		lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
		/* send outstanding frames, if any (resume / reconnect) */
		lapd_send_i(lctx, __LINE__);
		/* send notification to L3 */
		rc = send_dl_simple(PRIM_DL_EST, PRIM_OP_CONFIRM, lctx);
		msgb_free(msg);
		break;
	case LAPD_U_FRMR:
		LOGP(DLLAPD, LOGL_NOTICE, "Frame reject received\n");
		/* send MDL ERROR INIDCATION to L3 */
		mdl_error(MDL_CAUSE_FRMR, lctx);
		msgb_free(msg);
		/* reestablish */
		if (!dl->reestablish)
			break;
		LOGP(DLLAPD, LOGL_NOTICE, "Performing reestablishment.\n");
		rc = lapd_reestablish(dl);
		break;
	default:
		/* G.3.1 */
		LOGP(DLLAPD, LOGL_NOTICE, "Unnumbered frame not allowed.\n");
		msgb_free(msg);
		mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
		return -EINVAL;
	}
	return rc;
}

/* Receive a LAPD S (Supervisory) message from L1 */
static int lapd_rx_s(struct msgb *msg, struct lapd_msg_ctx *lctx)
{
	struct lapd_datalink *dl = lctx->dl;
	int length = lctx->length;

	if (length > 0 || lctx->more) {
		/* G.4.3 If a supervisory frame is received with L>0 or
		 * with the M bit set to "1", an MDL-ERROR-INDICATION
		 * primitive with cause "S frame with incorrect
		 * parameters" is sent to the mobile management entity. */
		LOGP(DLLAPD, LOGL_ERROR,
				"S frame with incorrect parameters\n");
		msgb_free(msg);
		mdl_error(MDL_CAUSE_SFRM_INC_PARAM, lctx);
		return -EIO;
	}

	if (lctx->cr == dl->cr.rem2loc.resp
	 && lctx->p_f
	 && dl->state != LAPD_STATE_TIMER_RECOV) {
		/* 5.4.2.2: Inidcate error on supervisory reponse F=1 */
		LOGP(DLLAPD, LOGL_NOTICE, "S frame response with F=1 error\n");
		mdl_error(MDL_CAUSE_UNSOL_SPRV_RESP, lctx);
	}

	switch (dl->state) {
	case LAPD_STATE_IDLE:
		/* if P=1, respond DM with F=1 (5.2.2) */
		/* 5.4.5 all other frame types shall be discarded */
		if (lctx->p_f)
			lapd_send_dm(lctx); /* F=P */
		/* fall though */
	case LAPD_STATE_SABM_SENT:
	case LAPD_STATE_DISC_SENT:
		LOGP(DLLAPD, LOGL_NOTICE, "S frame ignored in this state\n");
		msgb_free(msg);
		return 0;
	}
	switch (lctx->s_u) {
	case LAPD_S_RR:
		LOGP(DLLAPD, LOGL_INFO, "RR received in state %s\n",
			lapd_state_names[dl->state]);
		/* 5.5.3.1: Acknowlege all tx frames up the the N(R)-1 */
		lapd_acknowledge(lctx);

		/* 5.5.3.2 */
		if (lctx->cr == dl->cr.rem2loc.cmd
		 && lctx->p_f) {
		 	if (!dl->own_busy && !dl->seq_err_cond) {
				LOGP(DLLAPD, LOGL_INFO, "RR frame command "
					"with polling bit set and we are not "
					"busy, so we reply with RR frame "
					"response\n");
				lapd_send_rr(lctx, 1, 0);
				/* NOTE: In case of sequence error condition,
				 * the REJ frame has been transmitted when
				 * entering the condition, so it has not be
				 * done here
				 */
			} else if (dl->own_busy) {
				LOGP(DLLAPD, LOGL_INFO, "RR frame command "
					"with polling bit set and we are busy, "
					"so we reply with RR frame response\n");
				lapd_send_rnr(lctx, 1, 0);
			}
		} else if (lctx->cr == dl->cr.rem2loc.resp
			&& lctx->p_f
			&& dl->state == LAPD_STATE_TIMER_RECOV) {
			LOGP(DLLAPD, LOGL_INFO, "RR response with F==1, "
				"and we are in timer recovery state, so "
				"we leave that state\n");
			/* V(S) to the N(R) in the RR frame */
			dl->v_send = lctx->n_recv;
			/* stop Timer T200 */
			lapd_stop_t200(dl);
			/* 5.5.7 Clear timer recovery condition */
			lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
		}
		/* Send message, if possible due to acknowledged data */
		lapd_send_i(lctx, __LINE__);

		break;
	case LAPD_S_RNR:
		LOGP(DLLAPD, LOGL_INFO, "RNR received in state %s\n",
			lapd_state_names[dl->state]);
		/* 5.5.3.1: Acknowlege all tx frames up the the N(R)-1 */
		lapd_acknowledge(lctx);

		/* 5.5.5 */
		/* Set peer receiver busy condition */
		dl->peer_busy = 1;

		if (lctx->p_f) {
			if (lctx->cr == dl->cr.rem2loc.cmd) {
				if (!dl->own_busy) {
					LOGP(DLLAPD, LOGL_INFO, "RNR poll "
						"command and we are not busy, "
						"so we reply with RR final "
						"response\n");
					/* Send RR with F=1 */
					lapd_send_rr(lctx, 1, 0);
				} else {
					LOGP(DLLAPD, LOGL_INFO, "RNR poll "
						"command and we are busy, so "
						"we reply with RNR final "
						"response\n");
					/* Send RNR with F=1 */
					lapd_send_rnr(lctx, 1, 0);
				}
			} else if (dl->state == LAPD_STATE_TIMER_RECOV) {
				LOGP(DLLAPD, LOGL_INFO, "RNR poll response "
					"and we in timer recovery state, so "
					"we leave that state\n");
				/* 5.5.7 Clear timer recovery condition */
				lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
				/* V(S) to the N(R) in the RNR frame */
				dl->v_send = lctx->n_recv;
			}
		} else
			LOGP(DLLAPD, LOGL_INFO, "RNR not polling/final state "
				"received\n");

		/* Send message, if possible due to acknowledged data */
		lapd_send_i(lctx, __LINE__);

		break;
	case LAPD_S_REJ:
		LOGP(DLLAPD, LOGL_INFO, "REJ received in state %s\n",
			lapd_state_names[dl->state]);
		/* 5.5.3.1: Acknowlege all tx frames up the the N(R)-1 */
		lapd_acknowledge(lctx);

		/* 5.5.4.1 */
		if (dl->state != LAPD_STATE_TIMER_RECOV) {
			/* Clear an existing peer receiver busy condition */
			dl->peer_busy = 0;
			/* V(S) and V(A) to the N(R) in the REJ frame */
			dl->v_send = dl->v_ack = lctx->n_recv;
			/* stop Timer T200 */
			lapd_stop_t200(dl);
			/* 5.5.3.2 */
			if (lctx->cr == dl->cr.rem2loc.cmd && lctx->p_f) {
				if (!dl->own_busy && !dl->seq_err_cond) {
					LOGP(DLLAPD, LOGL_INFO, "REJ poll "
						"command not in timer recovery "
						"state and not in own busy "
						"condition received, so we "
						"respond with RR final "
						"response\n");
					lapd_send_rr(lctx, 1, 0);
					/* NOTE: In case of sequence error
					 * condition, the REJ frame has been
					 * transmitted when entering the
					 * condition, so it has not be done
					 * here
				 	 */
				} else if (dl->own_busy) {
					LOGP(DLLAPD, LOGL_INFO, "REJ poll "
						"command not in timer recovery "
						"state and in own busy "
						"condition received, so we "
						"respond with RNR final "
						"response\n");
					lapd_send_rnr(lctx, 1, 0);
				}
			} else
				LOGP(DLLAPD, LOGL_INFO, "REJ response or not "
					"polling command not in timer recovery "
					"state received\n");
			/* send MDL ERROR INIDCATION to L3 */
			if (lctx->cr == dl->cr.rem2loc.resp && lctx->p_f) {
				mdl_error(MDL_CAUSE_UNSOL_SPRV_RESP, lctx);
			}

		} else if (lctx->cr == dl->cr.rem2loc.resp && lctx->p_f) {
			LOGP(DLLAPD, LOGL_INFO, "REJ poll response in timer "
				"recovery state received\n");
			/* Clear an existing peer receiver busy condition */
			dl->peer_busy = 0;
			/* V(S) and V(A) to the N(R) in the REJ frame */
			dl->v_send = dl->v_ack = lctx->n_recv;
			/* stop Timer T200 */
			lapd_stop_t200(dl);
			/* 5.5.7 Clear timer recovery condition */
			lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
		} else {
			/* Clear an existing peer receiver busy condition */
			dl->peer_busy = 0;
			/* V(S) and V(A) to the N(R) in the REJ frame */
			dl->v_send = dl->v_ack = lctx->n_recv;
			/* 5.5.3.2 */
			if (lctx->cr == dl->cr.rem2loc.cmd && lctx->p_f) {
				if (!dl->own_busy && !dl->seq_err_cond) {
					LOGP(DLLAPD, LOGL_INFO, "REJ poll "
						"command in timer recovery "
						"state and not in own busy "
						"condition received, so we "
						"respond with RR final "
						"response\n");
					lapd_send_rr(lctx, 1, 0);
					/* NOTE: In case of sequence error
					 * condition, the REJ frame has been
					 * transmitted when entering the
					 * condition, so it has not be done
					 * here
				 	 */
				} else if (dl->own_busy) {
					LOGP(DLLAPD, LOGL_INFO, "REJ poll "
						"command in timer recovery "
						"state and in own busy "
						"condition received, so we "
						"respond with RNR final "
						"response\n");
					lapd_send_rnr(lctx, 1, 0);
				}
			} else
				LOGP(DLLAPD, LOGL_INFO, "REJ response or not "
					"polling command in timer recovery "
					"state received\n");
		}

		/* FIXME: 5.5.4.2 2) */

		/* Send message, if possible due to acknowledged data */
		lapd_send_i(lctx, __LINE__);

		break;
	default:
		/* G.3.1 */
		LOGP(DLLAPD, LOGL_ERROR, "Supervisory frame not allowed.\n");
		msgb_free(msg);
		mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
		return -EINVAL;
	}
	msgb_free(msg);
	return 0;
}

/* Receive a LAPD I (Information) message from L1 */
static int lapd_rx_i(struct msgb *msg, struct lapd_msg_ctx *lctx)
{
	struct lapd_datalink *dl = lctx->dl;
	//uint8_t nr = lctx->n_recv;
	uint8_t ns = lctx->n_send;
	int length = lctx->length;
	int rc;

	LOGP(DLLAPD, LOGL_INFO, "I received in state %s on SAPI(%u)\n",
		lapd_state_names[dl->state], lctx->sapi);
		
	/* G.2.2 Wrong value of the C/R bit */
	if (lctx->cr == dl->cr.rem2loc.resp) {
		LOGP(DLLAPD, LOGL_ERROR, "I frame response not allowed\n");
		msgb_free(msg);
		mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
		return -EINVAL;
	}

	if (length == 0 || length > lctx->n201) {
		/* G.4.2 If the length indicator of an I frame is set
		 * to a numerical value L>N201 or L=0, an MDL-ERROR-INDICATION
		 * primitive with cause "I frame with incorrect length"
		 * is sent to the mobile management entity. */
		LOGP(DLLAPD, LOGL_ERROR, "I frame length not allowed\n");
		msgb_free(msg);
		mdl_error(MDL_CAUSE_IFRM_INC_LEN, lctx);
		return -EIO;
	}

	/* G.4.2 If the numerical value of L is L<N201 and the M
	 * bit is set to "1", then an MDL-ERROR-INDICATION primitive with
	 * cause "I frame with incorrect use of M bit" is sent to the
	 * mobile management entity. */
	if (lctx->more && length < lctx->n201) {
		LOGP(DLLAPD, LOGL_ERROR, "I frame with M bit too short\n");
		msgb_free(msg);
		mdl_error(MDL_CAUSE_IFRM_INC_MBITS, lctx);
		return -EIO;
	}

	switch (dl->state) {
	case LAPD_STATE_IDLE:
		/* if P=1, respond DM with F=1 (5.2.2) */
		/* 5.4.5 all other frame types shall be discarded */
		if (lctx->p_f)
			lapd_send_dm(lctx); /* F=P */
		/* fall though */
	case LAPD_STATE_SABM_SENT:
	case LAPD_STATE_DISC_SENT:
		LOGP(DLLAPD, LOGL_NOTICE, "I frame ignored in this state\n");
		msgb_free(msg);
		return 0;
	}

	/* 5.7.1: N(s) sequence error */
	if (ns != dl->v_recv) {
		LOGP(DLLAPD, LOGL_NOTICE, "N(S) sequence error: N(S)=%u, "
		     "V(R)=%u\n", ns, dl->v_recv);
		/* discard data */
		msgb_free(msg);
		if (dl->seq_err_cond != 1) {
			/* FIXME: help me understand what exactly todo here
			*/
			dl->seq_err_cond = 1;
			lapd_send_rej(lctx, lctx->p_f);
		} else {
			/* If there are two subsequent sequence errors received,
			 * ignore it. (Ignore every second subsequent error.)
			 * This happens if our reply with the REJ is too slow,
			 * so the remote gets a T200 timeout and sends another
			 * frame with a sequence error.
			 * Test showed that replying with two subsequent REJ
			 * messages could the remote L2 process to abort.
			 * Replying too slow shouldn't happen, but may happen
			 * over serial link between BB and LAPD.
			 */
			dl->seq_err_cond = 2;
		}
		/* Even if N(s) sequence error, acknowledge to N(R)-1 */
		/* 5.5.3.1: Acknowlege all transmitted frames up the N(R)-1 */
		lapd_acknowledge(lctx); /* V(A) is also set here */

		/* Send message, if possible due to acknowledged data */
		lapd_send_i(lctx, __LINE__);

		return 0;
	}
	dl->seq_err_cond = 0;

	/* Increment receiver state */
	dl->v_recv = inc_mod(dl->v_recv, dl->v_range);
	LOGP(DLLAPD, LOGL_INFO, "incrementing V(R) to %u\n", dl->v_recv);

	/* 5.5.3.1: Acknowlege all transmitted frames up the the N(R)-1 */
	lapd_acknowledge(lctx); /* V(A) is also set here */

	/* Only if we are not in own receiver busy condition */
	if (!dl->own_busy) {
		/* if the frame carries a complete segment */
		if (!lctx->more && !dl->rcv_buffer) {
			LOGP(DLLAPD, LOGL_INFO, "message in single I frame\n");
			/* send a DATA INDICATION to L3 */
			msgb_trim(msg, length);
			rc = send_dl_l3(PRIM_DL_DATA, PRIM_OP_INDICATION, lctx,
				msg);
		} else {
			/* create rcv_buffer */
			if (!dl->rcv_buffer) {
				LOGP(DLLAPD, LOGL_INFO, "message in multiple "
					"I frames (first message)\n");
				dl->rcv_buffer = lapd_msgb_alloc(dl->maxf,
					"LAPD RX");
				dl->rcv_buffer->l3h = dl->rcv_buffer->data;
			}
			/* concat. rcv_buffer */
			if (msgb_l3len(dl->rcv_buffer) + length > dl->maxf) {
				LOGP(DLLAPD, LOGL_NOTICE, "Received frame "
					"overflow!\n");
			} else {
				memcpy(msgb_put(dl->rcv_buffer, length),
					msg->l3h, length);
			}
			/* if the last segment was received */
			if (!lctx->more) {
				LOGP(DLLAPD, LOGL_INFO, "message in multiple "
					"I frames (last message)\n");
				rc = send_dl_l3(PRIM_DL_DATA,
					PRIM_OP_INDICATION, lctx,
					dl->rcv_buffer);
				dl->rcv_buffer = NULL;
			} else
				LOGP(DLLAPD, LOGL_INFO, "message in multiple "
					"I frames (next message)\n");
			msgb_free(msg);

		}
	} else
		LOGP(DLLAPD, LOGL_INFO, "I frame ignored during own receiver "
			"busy condition\n");

	/* Check for P bit */
	if (lctx->p_f) {
		/* 5.5.2.1 */
		/* check if we are not in own receiver busy */
		if (!dl->own_busy) {
			LOGP(DLLAPD, LOGL_INFO, "we are not busy, send RR\n");
			/* Send RR with F=1 */
			rc = lapd_send_rr(lctx, 1, 0);
		} else {
			LOGP(DLLAPD, LOGL_INFO, "we are busy, send RNR\n");
			/* Send RNR with F=1 */
			rc = lapd_send_rnr(lctx, 1, 0);
		}
	} else {
		/* 5.5.2.2 */
		/* check if we are not in own receiver busy */
		if (!dl->own_busy) {
			/* NOTE: V(R) is already set above */
			rc = lapd_send_i(lctx, __LINE__);

			/* if update_pending_iframe returns 0 it updated
			 * the lapd header of an iframe in the tx queue */
			if (rc && dl->update_pending_frames)
				rc = dl->update_pending_frames(lctx);

			if (rc) {
				LOGP(DLLAPD, LOGL_INFO, "we are not busy and "
					"have no pending data, send RR\n");
				/* Send RR with F=0 */
				return lapd_send_rr(lctx, 0, 0);
			}
			/* all I or one RR is sent, we are done */
			return 0;
		} else {
			LOGP(DLLAPD, LOGL_INFO, "we are busy, send RNR\n");
			/* Send RNR with F=0 */
			rc = lapd_send_rnr(lctx, 0, 0);
		}
	}

	/* Send message, if possible due to acknowledged data */
	lapd_send_i(lctx, __LINE__);

	return rc;
}

/* Receive a LAPD message from L1 */
int lapd_ph_data_ind(struct msgb *msg, struct lapd_msg_ctx *lctx)
{
	int rc;

	switch (lctx->format) {
	case LAPD_FORM_U:
		rc = lapd_rx_u(msg, lctx);
		break;
	case LAPD_FORM_S:
		rc = lapd_rx_s(msg, lctx);
		break;
	case LAPD_FORM_I:
		rc = lapd_rx_i(msg, lctx);
		break;
	default:
		LOGP(DLLAPD, LOGL_NOTICE, "unknown LAPD format\n");
		msgb_free(msg);
		rc = -EINVAL;
	}
	return rc;
}

/* L3 -> L2 */

/* send unit data */
static int lapd_udata_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
{
	struct lapd_datalink *dl = lctx->dl;
	struct msgb *msg = dp->oph.msg;
	struct lapd_msg_ctx nctx;

	memcpy(&nctx, lctx, sizeof(nctx));
	/* keep nctx.ldp */
	/* keep nctx.sapi */
	/* keep nctx.tei */
	nctx.cr = dl->cr.loc2rem.cmd;
	nctx.format = LAPD_FORM_U;
	nctx.s_u = LAPD_U_UI;
	/* keep nctx.p_f */
	nctx.length = msg->len;
	nctx.more = 0;

	return dl->send_ph_data_req(&nctx, msg);
}

/* request link establishment */
static int lapd_est_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
{
	struct lapd_datalink *dl = lctx->dl;
	struct msgb *msg = dp->oph.msg;
	struct lapd_msg_ctx nctx;

	if (msg->len)
		LOGP(DLLAPD, LOGL_INFO, "perform establishment with content "
			"(SABM)\n");
	else
		LOGP(DLLAPD, LOGL_INFO, "perform normal establishm. (SABM)\n");

	/* Flush send-queue */
	/* Clear send-buffer */
	lapd_dl_flush_send(dl);
	/* be sure that history is empty */
	lapd_dl_flush_hist(dl);

	/* save message context for further use */
	memcpy(&dl->lctx, lctx, sizeof(dl->lctx));

	/* Discard partly received L3 message */
	msgb_free(dl->rcv_buffer);
	dl->rcv_buffer = NULL;

	/* assemble message */
	memcpy(&nctx, &dl->lctx, sizeof(nctx));
	/* keep nctx.ldp */
	/* keep nctx.sapi */
	/* keep nctx.tei */
	nctx.cr = dl->cr.loc2rem.cmd;
	nctx.format = LAPD_FORM_U;
	nctx.s_u = (dl->use_sabme) ? LAPD_U_SABME : LAPD_U_SABM;
	nctx.p_f = 1;
	nctx.length = msg->len;
	nctx.more = 0;

	/* Transmit-buffer carries exactly one segment */
	dl->tx_hist[0].msg = lapd_msgb_alloc(msg->len, "HIST");
	msgb_put(dl->tx_hist[0].msg, msg->len);
	if (msg->len)
		memcpy(dl->tx_hist[0].msg->data, msg->l3h, msg->len);
	dl->tx_hist[0].more = 0;
	/* set Vs to 0, because it is used as index when resending SABM */
	dl->v_send = 0;
	
	/* Set states */
	dl->own_busy = dl->peer_busy = 0;
	dl->retrans_ctr = 0;
	lapd_dl_newstate(dl, LAPD_STATE_SABM_SENT);

	/* Tramsmit and start T200 */
	dl->send_ph_data_req(&nctx, msg);
	lapd_start_t200(dl);

	return 0;
}

/* send data */
static int lapd_data_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
{
	struct lapd_datalink *dl = lctx->dl;
	struct msgb *msg = dp->oph.msg;

	if (msgb_l3len(msg) == 0) {
		LOGP(DLLAPD, LOGL_ERROR,
			"writing an empty message is not possible.\n");
		msgb_free(msg);
		return -1;
	}

	LOGP(DLLAPD, LOGL_INFO,
	     "writing message to send-queue: l3len: %d\n", msgb_l3len(msg));

	/* Write data into the send queue */
	msgb_enqueue(&dl->send_queue, msg);

	/* Send message, if possible */
	lapd_send_i(&dl->lctx, __LINE__);

	return 0;
}

/* Send next I frame from queued/buffered data */
static int lapd_send_i(struct lapd_msg_ctx *lctx, int line)
{
	struct lapd_datalink *dl = lctx->dl;
	uint8_t k = dl->k;
	uint8_t h;
	struct msgb *msg;
	int length, left;
	int rc = - 1; /* we sent nothing */
	struct lapd_msg_ctx nctx;


	LOGP(DLLAPD, LOGL_INFO, "%s() called from line %d\n", __func__, line);

	next_frame:

	if (dl->peer_busy) {
		LOGP(DLLAPD, LOGL_INFO, "peer busy, not sending\n");
		return rc;
	}

	if (dl->state == LAPD_STATE_TIMER_RECOV) {
		LOGP(DLLAPD, LOGL_INFO, "timer recovery, not sending\n");
		return rc;
	}

	/* If the send state variable V(S) is equal to V(A) plus k
	 * (where k is the maximum number of outstanding I frames - see
	 * subclause 5.8.4), the data link layer entity shall not transmit any
	 * new I frames, but shall retransmit an I frame as a result
	 * of the error recovery procedures as described in subclauses 5.5.4 and
	 * 5.5.7. */
	if (dl->v_send == add_mod(dl->v_ack, k, dl->v_range)) {
		LOGP(DLLAPD, LOGL_INFO, "k frames outstanding, not sending "
			"more (k=%u V(S)=%u V(A)=%u)\n", k, dl->v_send,
			dl->v_ack);
		return rc;
	}

	h = do_mod(dl->v_send, dl->range_hist);

	/* if we have no tx_hist yet, we create it */
	if (!dl->tx_hist[h].msg) {
		/* Get next message into send-buffer, if any */
		if (!dl->send_buffer) {
			next_message:
			dl->send_out = 0;
			dl->send_buffer = msgb_dequeue(&dl->send_queue);
			/* No more data to be sent */
			if (!dl->send_buffer)
				return rc;
			LOGP(DLLAPD, LOGL_INFO, "get message from "
				"send-queue\n");
		}

		/* How much is left in the send-buffer? */
		left = msgb_l3len(dl->send_buffer) - dl->send_out;
		/* Segment, if data exceeds N201 */
		length = left;
		if (length > lctx->n201)
			length = lctx->n201;
		LOGP(DLLAPD, LOGL_INFO, "msg-len %d sent %d left %d N201 %d "
			"length %d first byte %02x\n",
			msgb_l3len(dl->send_buffer), dl->send_out, left,
			lctx->n201, length, dl->send_buffer->l3h[0]);
		/* If message in send-buffer is completely sent */
		if (left == 0) {
			msgb_free(dl->send_buffer);
			dl->send_buffer = NULL;
			goto next_message;
		}

		LOGP(DLLAPD, LOGL_INFO, "send I frame %sV(S)=%d\n",
			(left > length) ? "segment " : "", dl->v_send);

		/* Create I frame (segment) and transmit-buffer content */
		msg = lapd_msgb_alloc(length, "LAPD I");
		msg->l3h = msgb_put(msg, length);
		/* assemble message */
		memcpy(&nctx, &dl->lctx, sizeof(nctx));
		/* keep nctx.ldp */
		/* keep nctx.sapi */
		/* keep nctx.tei */
		nctx.cr = dl->cr.loc2rem.cmd;
		nctx.format = LAPD_FORM_I;
		nctx.p_f = 0;
		nctx.n_send = dl->v_send;
		nctx.n_recv = dl->v_recv;
		nctx.length = length;
		if (left > length)
			nctx.more = 1;
		else
			nctx.more = 0;
		if (length)
			memcpy(msg->l3h, dl->send_buffer->l3h + dl->send_out,
				length);
		/* store in tx_hist */
		dl->tx_hist[h].msg = lapd_msgb_alloc(msg->len, "HIST");
		msgb_put(dl->tx_hist[h].msg, msg->len);
		if (length)
			memcpy(dl->tx_hist[h].msg->data, msg->l3h, msg->len);
		dl->tx_hist[h].more = nctx.more;
		/* Add length to track how much is already in the tx buffer */
		dl->send_out += length;
	} else {
		LOGP(DLLAPD, LOGL_INFO, "resend I frame from tx buffer "
			"V(S)=%d\n", dl->v_send);

		/* Create I frame (segment) from tx_hist */
		length = dl->tx_hist[h].msg->len;
		msg = lapd_msgb_alloc(length, "LAPD I resend");
		msg->l3h = msgb_put(msg, length);
		/* assemble message */
		memcpy(&nctx, &dl->lctx, sizeof(nctx));
		/* keep nctx.ldp */
		/* keep nctx.sapi */
		/* keep nctx.tei */
		nctx.cr = dl->cr.loc2rem.cmd;
		nctx.format = LAPD_FORM_I;
		nctx.p_f = 0;
		nctx.n_send = dl->v_send;
		nctx.n_recv = dl->v_recv;
		nctx.length = length;
		nctx.more = dl->tx_hist[h].more;
		if (length)
			memcpy(msg->l3h, dl->tx_hist[h].msg->data, length);
	}

	/* The value of the send state variable V(S) shall be incremented by 1
	 * at the end of the transmission of the I frame */
	dl->v_send = inc_mod(dl->v_send, dl->v_range);

	/* If timer T200 is not running at the time right before transmitting a
	 * frame, when the PH-READY-TO-SEND primitive is received from the
	 * physical layer., it shall be set. */
	if (!osmo_timer_pending(&dl->t200)) {
		/* stop Timer T203, if running */
		lapd_stop_t203(dl);
		/* start Timer T200 */
		lapd_start_t200(dl);
	}

	dl->send_ph_data_req(&nctx, msg);

	rc = 0; /* we sent something */
	goto next_frame;
}

/* request link suspension */
static int lapd_susp_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
{
	struct lapd_datalink *dl = lctx->dl;
	struct msgb *msg = dp->oph.msg;

	LOGP(DLLAPD, LOGL_INFO, "perform suspension\n");

	/* put back the send-buffer to the send-queue (first position) */
	if (dl->send_buffer) {
		LOGP(DLLAPD, LOGL_INFO, "put frame in sendbuffer back to "
			"queue\n");
		llist_add(&dl->send_buffer->list, &dl->send_queue);
		dl->send_buffer = NULL;
	} else
		LOGP(DLLAPD, LOGL_INFO, "no frame in sendbuffer\n");

	/* Clear transmit buffer, but keep send buffer */
	lapd_dl_flush_tx(dl);
	/* Stop timers (there is no state change, so we must stop all timers */
	lapd_stop_t200(dl);
	lapd_stop_t203(dl);

	msgb_free(msg);

	return send_dl_simple(PRIM_DL_SUSP, PRIM_OP_CONFIRM, &dl->lctx);
}

/* request, resume or reconnect of link */
static int lapd_res_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
{
	struct lapd_datalink *dl = lctx->dl;
	struct msgb *msg = dp->oph.msg;
	struct lapd_msg_ctx nctx;

	LOGP(DLLAPD, LOGL_INFO, "perform re-establishment (SABM) length=%d\n",
		msg->len);
	
	/* be sure that history is empty */
	lapd_dl_flush_hist(dl);

	/* save message context for further use */
	memcpy(&dl->lctx, lctx, sizeof(dl->lctx));

	/* Replace message in the send-buffer (reconnect) */
	msgb_free(dl->send_buffer);
	dl->send_buffer = NULL;

	dl->send_out = 0;
	if (msg->len) {
		/* Write data into the send buffer, to be sent first */
		dl->send_buffer = msg;
	} else {
		msgb_free(msg);
		msg = NULL;
		dl->send_buffer = NULL;
	}

	/* Discard partly received L3 message */
	msgb_free(dl->rcv_buffer);
	dl->rcv_buffer = NULL;

	/* Create new msgb (old one is now free) */
	msg = lapd_msgb_alloc(0, "LAPD SABM");
	msg->l3h = msg->data;
	/* assemble message */
	memcpy(&nctx, &dl->lctx, sizeof(nctx));
	/* keep nctx.ldp */
	/* keep nctx.sapi */
	/* keep nctx.tei */
	nctx.cr = dl->cr.loc2rem.cmd;
	nctx.format = LAPD_FORM_U;
	nctx.s_u = (dl->use_sabme) ? LAPD_U_SABME : LAPD_U_SABM;
	nctx.p_f = 1;
	nctx.length = 0;
	nctx.more = 0;

	dl->tx_hist[0].msg = lapd_msgb_alloc(msg->len, "HIST");
	msgb_put(dl->tx_hist[0].msg, msg->len);
	if (msg->len)
		memcpy(dl->tx_hist[0].msg->data, msg->l3h, msg->len);
	dl->tx_hist[0].more = 0;
	/* set Vs to 0, because it is used as index when resending SABM */
	dl->v_send = 0;

	/* Set states */
	dl->own_busy = dl->peer_busy = 0;
	dl->retrans_ctr = 0;
	lapd_dl_newstate(dl, LAPD_STATE_SABM_SENT);

	/* Tramsmit and start T200 */
	dl->send_ph_data_req(&nctx, msg);
	lapd_start_t200(dl);

	return 0;
}

/* requesst release of link */
static int lapd_rel_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
{
	struct lapd_datalink *dl = lctx->dl;
	struct msgb *msg = dp->oph.msg;
	struct lapd_msg_ctx nctx;

	/* local release */
	if (dp->u.rel_req.mode) {
		LOGP(DLLAPD, LOGL_INFO, "perform local release\n");
		msgb_free(msg);
		/* stop Timer T200 */
		lapd_stop_t200(dl);
		/* enter idle state, T203 is stopped here, if running */
		lapd_dl_newstate(dl, LAPD_STATE_IDLE);
		/* flush buffers */
		lapd_dl_flush_tx(dl);
		lapd_dl_flush_send(dl);
		/* send notification to L3 */
		return send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, &dl->lctx);
	}

	/* in case we are already disconnecting */
	if (dl->state == LAPD_STATE_DISC_SENT)
		return -EBUSY;

	/* flush tx_hist */
	lapd_dl_flush_hist(dl);

	LOGP(DLLAPD, LOGL_INFO, "perform normal release (DISC)\n");

	/* Push LAPD header on msgb */
	/* assemble message */
	memcpy(&nctx, &dl->lctx, sizeof(nctx));
	/* keep nctx.ldp */
	/* keep nctx.sapi */
	/* keep nctx.tei */
	nctx.cr = dl->cr.loc2rem.cmd;
	nctx.format = LAPD_FORM_U;
	nctx.s_u = LAPD_U_DISC;
	nctx.p_f = 1;
	nctx.length = 0;
	nctx.more = 0;

	dl->tx_hist[0].msg = lapd_msgb_alloc(msg->len, "HIST");
	msgb_put(dl->tx_hist[0].msg, msg->len);
	if (msg->len)
		memcpy(dl->tx_hist[0].msg->data, msg->l3h, msg->len);
	dl->tx_hist[0].more = 0;
	/* set Vs to 0, because it is used as index when resending DISC */
	dl->v_send = 0;
	
	/* Set states */
	dl->own_busy = dl->peer_busy = 0;
	dl->retrans_ctr = 0;
	lapd_dl_newstate(dl, LAPD_STATE_DISC_SENT);

	/* Tramsmit and start T200 */
	dl->send_ph_data_req(&nctx, msg);
	lapd_start_t200(dl);

	return 0;
}

/* request release of link in idle state */
static int lapd_rel_req_idle(struct osmo_dlsap_prim *dp,
	struct lapd_msg_ctx *lctx)
{
	struct lapd_datalink *dl = lctx->dl;
	struct msgb *msg = dp->oph.msg;

	msgb_free(msg);

	/* send notification to L3 */
	return send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, &dl->lctx);
}

/* statefull handling for DL SAP messages from L3 */
static const struct l2downstate {
	uint32_t	states;
	int		prim, op;
	const char 	*name;
	int		(*rout) (struct osmo_dlsap_prim *dp,
					struct lapd_msg_ctx *lctx);
} l2downstatelist[] = {
	/* create and send UI command */
	{ALL_STATES,
	 PRIM_DL_UNIT_DATA, PRIM_OP_REQUEST, 
	 "DL-UNIT-DATA-REQUEST", lapd_udata_req},

	/* create and send SABM command */
	{SBIT(LAPD_STATE_IDLE),
	 PRIM_DL_EST, PRIM_OP_REQUEST,
	 "DL-ESTABLISH-REQUEST", lapd_est_req},

	/* create and send I command */
	{SBIT(LAPD_STATE_MF_EST) |
	 SBIT(LAPD_STATE_TIMER_RECOV),
	 PRIM_DL_DATA, PRIM_OP_REQUEST,
	 "DL-DATA-REQUEST", lapd_data_req},

	/* suspend datalink */
	{SBIT(LAPD_STATE_MF_EST) |
	 SBIT(LAPD_STATE_TIMER_RECOV),
	 PRIM_DL_SUSP, PRIM_OP_REQUEST,
	 "DL-SUSPEND-REQUEST", lapd_susp_req},

	/* create and send SABM command (resume) */
	{SBIT(LAPD_STATE_MF_EST) |
	 SBIT(LAPD_STATE_TIMER_RECOV),
	 PRIM_DL_RES, PRIM_OP_REQUEST,
	 "DL-RESUME-REQUEST", lapd_res_req},

	/* create and send SABM command (reconnect) */
	{SBIT(LAPD_STATE_IDLE) |
	 SBIT(LAPD_STATE_MF_EST) |
	 SBIT(LAPD_STATE_TIMER_RECOV),
	 PRIM_DL_RECON, PRIM_OP_REQUEST,
	 "DL-RECONNECT-REQUEST", lapd_res_req},

	/* create and send DISC command */
	{SBIT(LAPD_STATE_SABM_SENT) |
	 SBIT(LAPD_STATE_MF_EST) |
	 SBIT(LAPD_STATE_TIMER_RECOV) |
	 SBIT(LAPD_STATE_DISC_SENT),
	 PRIM_DL_REL, PRIM_OP_REQUEST,
	 "DL-RELEASE-REQUEST", lapd_rel_req},

	/* release in idle state */
	{SBIT(LAPD_STATE_IDLE),
	 PRIM_DL_REL, PRIM_OP_REQUEST,
	 "DL-RELEASE-REQUEST", lapd_rel_req_idle},
};

#define L2DOWNSLLEN \
	(sizeof(l2downstatelist) / sizeof(struct l2downstate))

int lapd_recv_dlsap(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
{
	struct lapd_datalink *dl = lctx->dl;
	int i, supported = 0;
	struct msgb *msg = dp->oph.msg;
	int rc;

	/* find function for current state and message */
	for (i = 0; i < L2DOWNSLLEN; i++) {
		if (dp->oph.primitive == l2downstatelist[i].prim
		 && dp->oph.operation == l2downstatelist[i].op) {
			supported = 1;
		 	if ((SBIT(dl->state) & l2downstatelist[i].states))
				break;
		}
	}
	if (!supported) {
		LOGP(DLLAPD, LOGL_NOTICE, "Message %u/%u unsupported.\n",
			dp->oph.primitive, dp->oph.operation);
		msgb_free(msg);
		return 0;
	}
	if (i == L2DOWNSLLEN) {
		LOGP(DLLAPD, LOGL_NOTICE, "Message %u/%u unhandled at this "
			"state %s.\n", dp->oph.primitive, dp->oph.operation,
			lapd_state_names[dl->state]);
		msgb_free(msg);
		return 0;
	}

	LOGP(DLLAPD, LOGL_INFO, "Message %s received in state %s\n",
		l2downstatelist[i].name, lapd_state_names[dl->state]);

	rc = l2downstatelist[i].rout(dp, lctx);

	return rc;
}

/*! @} */
