/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2000-2002  Maxim Krasnyansky <maxk@qualcomm.com>
 *  Copyright (C) 2003-2011  Marcel Holtmann <marcel@holtmann.org>
 *
 *
 *  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 St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/l2cap.h>

#include "parser.h"
#include "sdp.h"

typedef struct {
	uint16_t handle;
	struct frame frm;
} handle_info;
#define HANDLE_TABLE_SIZE 10

static handle_info handle_table[HANDLE_TABLE_SIZE];

typedef struct {
	uint16_t handle;
	uint16_t cid;
	uint16_t psm;
	uint16_t num;
	uint8_t mode;
} cid_info;
#define CID_TABLE_SIZE 20

static cid_info cid_table[2][CID_TABLE_SIZE];

#define SCID cid_table[0]
#define DCID cid_table[1]

static struct frame *add_handle(uint16_t handle)
{
	register handle_info *t = handle_table;
	register int i;

	for (i = 0; i < HANDLE_TABLE_SIZE; i++)
		if (!t[i].handle) {
			t[i].handle = handle;
			return &t[i].frm;
		}
	return NULL;
}

static struct frame *get_frame(uint16_t handle)
{
	register handle_info *t = handle_table;
	register int i;

	for (i = 0; i < HANDLE_TABLE_SIZE; i++)
		if (t[i].handle == handle)
			return &t[i].frm;

	return add_handle(handle);
}

static void add_cid(int in, uint16_t handle, uint16_t cid, uint16_t psm)
{
	register cid_info *table = cid_table[in];
	register int i, pos = -1;
	uint16_t num = 1;

	for (i = 0; i < CID_TABLE_SIZE; i++) {
		if ((pos < 0 && !table[i].cid) || table[i].cid == cid)
			pos = i;
		if (table[i].psm == psm)
			num++;
	}

	if (pos >= 0) {
		table[pos].handle = handle;
		table[pos].cid    = cid;
		table[pos].psm    = psm;
		table[pos].num    = num;
		table[pos].mode   = 0;
	}
}

static void del_cid(int in, uint16_t dcid, uint16_t scid)
{
	register int t, i;
	uint16_t cid[2];

	if (!in) {
		cid[0] = dcid;
		cid[1] = scid;
	} else {
		cid[0] = scid;
		cid[1] = dcid;
	}

	for (t = 0; t < 2; t++) {
		for (i = 0; i < CID_TABLE_SIZE; i++)
			if (cid_table[t][i].cid == cid[t]) {
				cid_table[t][i].handle = 0;
				cid_table[t][i].cid    = 0;
				cid_table[t][i].psm    = 0;
				cid_table[t][i].num    = 0;
				cid_table[t][i].mode   = 0;
				break;
			}
	}
}

static void del_handle(uint16_t handle)
{
	register int t, i;

	for (t = 0; t < 2; t++) {
		for (i = 0; i < CID_TABLE_SIZE; i++)
			if (cid_table[t][i].handle == handle) {
				cid_table[t][i].handle = 0;
				cid_table[t][i].cid    = 0;
				cid_table[t][i].psm    = 0;
				cid_table[t][i].num    = 0;
				cid_table[t][i].mode   = 0;
				break;
			}
	}
}
static uint16_t get_psm(int in, uint16_t cid)
{
	register cid_info *table = cid_table[in];
	register int i;

	for (i = 0; i < CID_TABLE_SIZE; i++)
		if (table[i].cid == cid)
			return table[i].psm;
	return parser.defpsm;
}

static uint16_t get_num(int in, uint16_t cid)
{
	register cid_info *table = cid_table[in];
	register int i;

	for (i = 0; i < CID_TABLE_SIZE; i++)
		if (table[i].cid == cid)
			return table[i].num;
	return 0;
}

static void set_mode(int in, uint16_t cid, uint8_t mode)
{
	register cid_info *table = cid_table[in];
	register int i;

	for (i = 0; i < CID_TABLE_SIZE; i++)
		if (table[i].cid == cid)
			table[i].mode = mode;
}

static uint8_t get_mode(int in, uint16_t cid)
{
	register cid_info *table = cid_table[in];
	register int i;

	for (i = 0; i < CID_TABLE_SIZE; i++)
		if (table[i].cid == cid)
			return table[i].mode;
	return 0;
}

static uint32_t get_val(uint8_t *ptr, uint8_t len)
{
	switch (len) {
	case 1:
		return *ptr;
	case 2:
		return btohs(bt_get_unaligned((uint16_t *) ptr));
	case 4:
		return btohl(bt_get_unaligned((uint32_t *) ptr));
	}
	return 0;
}

static char *reason2str(uint16_t reason)
{
	switch (reason) {
	case 0x0000:
		return "Command not understood";
	case 0x0001:
		return "Signalling MTU exceeded";
	case 0x0002:
		return "Invalid CID in request";
	default:
		return "Reserved";
	}
}

static char *connresult2str(uint16_t result)
{
	switch (result) {
	case 0x0000:
		return "Connection successful";
	case 0x0001:
		return "Connection pending";
	case 0x0002:
		return "Connection refused - PSM not supported";
	case 0x0003:
		return "Connection refused - security block";
	case 0x0004:
		return "Connection refused - no resources available";
	default:
		return "Reserved";
	}
}

static char *status2str(uint16_t status)
{
	switch (status) {
	case 0x0000:
		return "No futher information available";
	case 0x0001:
		return "Authentication pending";
	case 0x0002:
		return "Authorization pending";
	default:
		return "Reserved";
	}
}

static char *confresult2str(uint16_t result)
{
	switch (result) {
	case 0x0000:
		return "Success";
	case 0x0001:
		return "Failure - unacceptable parameters";
	case 0x0002:
		return "Failure - rejected (no reason provided)";
	case 0x0003:
		return "Failure - unknown options";
	default:
		return "Reserved";
	}
}
static char *inforesult2str(uint16_t result)
{
	switch (result) {
	case 0x0000:
		return "Success";
	case 0x0001:
		return "Not supported";
	default:
		return "Reserved";
	}
}

static char *type2str(uint8_t type)
{
	switch (type) {
	case 0x00:
		return "No traffic";
	case 0x01:
		return "Best effort";
	case 0x02:
		return "Guaranteed";
	default:
		return "Reserved";
	}
}

static char *mode2str(uint8_t mode)
{
	switch (mode) {
	case 0x00:
		return "Basic";
	case 0x01:
		return "Retransmission";
	case 0x02:
		return "Flow control";
	case 0x03:
		return "Enhanced Retransmission";
	case 0x04:
		return "Streaming";
	default:
		return "Reserved";
	}
}

static char *fcs2str(uint8_t fcs)
{
	switch (fcs) {
	case 0x00:
		return "No FCS";
	case 0x01:
		return "CRC16 Check";
	default:
		return "Reserved";
	}
}

static char *sar2str(uint8_t sar)
{
	switch (sar) {
	case 0x00:
		return "Unsegmented";
	case 0x01:
		return "Start";
	case 0x02:
		return "End";
	case 0x03:
		return "Continuation";
	default:
		return "Bad SAR";

	}
}

static char *supervisory2str(uint8_t supervisory)
{
	switch (supervisory) {
	case 0x00:
		return "Receiver Ready (RR)";
	case 0x01:
		return "Reject (REJ)";
	case 0x02:
		return "Receiver Not Ready (RNR)";
	case 0x03:
		return "Select Reject (SREJ)";
	default:
		return "Bad Supervisory";
	}
}

static inline void command_rej(int level, struct frame *frm)
{
	l2cap_cmd_rej *h = frm->ptr;
	uint16_t reason = btohs(h->reason);
	uint32_t cid;

	printf("Command rej: reason %d", reason);

	switch (reason) {
	case 0x0001:
		printf(" mtu %d\n", get_val(frm->ptr + L2CAP_CMD_REJ_SIZE, 2));
		break;
	case 0x0002:
		cid = get_val(frm->ptr + L2CAP_CMD_REJ_SIZE, 4);
		printf(" dcid 0x%4.4x scid 0x%4.4x\n", cid & 0xffff, cid >> 16);
		break;
	default:
		printf("\n");
		break;
	}

	p_indent(level + 1, frm);
	printf("%s\n", reason2str(reason));
}

static inline void conn_req(int level, struct frame *frm)
{
	l2cap_conn_req *h = frm->ptr;
	uint16_t psm = btohs(h->psm);
	uint16_t scid = btohs(h->scid);

	add_cid(frm->in, frm->handle, scid, psm);

	if (p_filter(FILT_L2CAP))
		return;

	printf("Connect req: psm %d scid 0x%4.4x\n", psm, scid);
}

static inline void conn_rsp(int level, struct frame *frm)
{
	l2cap_conn_rsp *h = frm->ptr;
	uint16_t scid = btohs(h->scid);
	uint16_t dcid = btohs(h->dcid);
	uint16_t result = btohs(h->result);
	uint16_t status = btohs(h->status);
	uint16_t psm;

	switch (h->result) {
	case L2CAP_CR_SUCCESS:
		if ((psm = get_psm(!frm->in, scid)))
			add_cid(frm->in, frm->handle, dcid, psm);
		break;

	case L2CAP_CR_PEND:
		break;

	default:
		del_cid(frm->in, dcid, scid);
		break;
	}

	if (p_filter(FILT_L2CAP))
		return;

	printf("Connect rsp: dcid 0x%4.4x scid 0x%4.4x result %d status %d\n",
		dcid, scid, result, status);

	p_indent(level + 1, frm);
	printf("%s", connresult2str(result));

	if (result == 0x0001)
		printf(" - %s\n", status2str(status));
	else
		printf("\n");
}

static void conf_rfc(void *ptr, int len, int in, uint16_t cid)
{
	uint8_t mode;

	mode = *((uint8_t *) ptr);
	set_mode(in, cid, mode);

	printf("RFC 0x%02x (%s", mode, mode2str(mode));
	if (mode >= 0x01 && mode <= 0x04) {
		uint8_t txwin, maxtrans;
		uint16_t rto, mto, mps;
		txwin = *((uint8_t *) (ptr + 1));
		maxtrans = *((uint8_t *) (ptr + 2));
		rto = btohs(bt_get_unaligned((uint16_t *) (ptr + 3)));
		mto = btohs(bt_get_unaligned((uint16_t *) (ptr + 5)));
		mps = btohs(bt_get_unaligned((uint16_t *) (ptr + 7)));
		printf(", TxWin %d, MaxTx %d, RTo %d, MTo %d, MPS %d",
					txwin, maxtrans, rto, mto, mps);
	}
	printf(")");
}

static void conf_fcs(void *ptr, int len)
{
	uint8_t fcs;

	fcs = *((uint8_t *) ptr);
	printf("FCS Option");
	if (len > 0)
		printf(" 0x%2.2x (%s)", fcs, fcs2str(fcs));
}

static void conf_opt(int level, void *ptr, int len, int in, uint16_t cid)
{
	p_indent(level, 0);
	while (len > 0) {
		l2cap_conf_opt *h = ptr;

		ptr += L2CAP_CONF_OPT_SIZE + h->len;
		len -= L2CAP_CONF_OPT_SIZE + h->len;

		if (h->type & 0x80)
			printf("[");

		switch (h->type & 0x7f) {
		case L2CAP_CONF_MTU:
			set_mode(in, cid, 0x00);
			printf("MTU");
			if (h->len > 0)
				printf(" %d", get_val(h->val, h->len));
			break;

		case L2CAP_CONF_FLUSH_TO:
			printf("FlushTO");
			if (h->len > 0)
				printf(" %d", get_val(h->val, h->len));
			break;

		case L2CAP_CONF_QOS:
			printf("QoS");
			if (h->len > 0)
				printf(" 0x%02x (%s)", *(h->val + 1), type2str(*(h->val + 1)));
			break;

		case L2CAP_CONF_RFC:
			conf_rfc(h->val, h->len, in, cid);
			break;

		case L2CAP_CONF_FCS:
			conf_fcs(h->val, h->len);
			break;

		default:
			printf("Unknown (type %2.2x, len %d)", h->type & 0x7f, h->len);
			break;
		}

		if (h->type & 0x80)
			printf("] ");
		else
			printf(" ");
	}
	printf("\n");
}

static void conf_list(int level, uint8_t *list, int len)
{
	int i;

	p_indent(level, 0);
	for (i = 0; i < len; i++) {
		switch (list[i] & 0x7f) {
		case L2CAP_CONF_MTU:
			printf("MTU ");
			break;
		case L2CAP_CONF_FLUSH_TO:
			printf("FlushTo ");
			break;
		case L2CAP_CONF_QOS:
			printf("QoS ");
			break;
		case L2CAP_CONF_RFC:
			printf("RFC ");
			break;
		case L2CAP_CONF_FCS:
			printf("FCS ");
			break;
		default:
			printf("%2.2x ", list[i] & 0x7f);
			break;
		}
	}
	printf("\n");
}

static inline void conf_req(int level, l2cap_cmd_hdr *cmd, struct frame *frm)
{
	l2cap_conf_req *h = frm->ptr;
	uint16_t dcid = btohs(h->dcid);
	int clen = btohs(cmd->len) - L2CAP_CONF_REQ_SIZE;

	if (p_filter(FILT_L2CAP))
		return;

	printf("Config req: dcid 0x%4.4x flags 0x%2.2x clen %d\n",
			dcid, btohs(h->flags), clen);

	if (clen > 0)
		conf_opt(level + 1, h->data, clen, frm->in, dcid);
}

static inline void conf_rsp(int level, l2cap_cmd_hdr *cmd, struct frame *frm)
{
	l2cap_conf_rsp *h = frm->ptr;
	uint16_t scid = btohs(h->scid);
	uint16_t result = btohs(h->result);
	int clen = btohs(cmd->len) - L2CAP_CONF_RSP_SIZE;

	if (p_filter(FILT_L2CAP))
		return;

	printf("Config rsp: scid 0x%4.4x flags 0x%2.2x result %d clen %d\n",
			scid, btohs(h->flags), result, clen);

	if (clen > 0) {
		if (result) {
			p_indent(level + 1, frm);
			printf("%s\n", confresult2str(result));
		}
		if (result == 0x0003)
			conf_list(level + 1, h->data, clen);
		else
			conf_opt(level + 1, h->data, clen, frm->in, scid);
	} else {
		p_indent(level + 1, frm);
		printf("%s\n", confresult2str(result));
	}
}

static inline void disconn_req(int level, struct frame *frm)
{
	l2cap_disconn_req *h = frm->ptr;

	if (p_filter(FILT_L2CAP))
		return;

	printf("Disconn req: dcid 0x%4.4x scid 0x%4.4x\n",
			btohs(h->dcid), btohs(h->scid));
}

static inline void disconn_rsp(int level, struct frame *frm)
{
	l2cap_disconn_rsp *h = frm->ptr;
	uint16_t dcid = btohs(h->dcid);
	uint16_t scid = btohs(h->scid);

	del_cid(frm->in, dcid, scid);

	if (p_filter(FILT_L2CAP))
		return;

	printf("Disconn rsp: dcid 0x%4.4x scid 0x%4.4x\n",
			btohs(h->dcid), btohs(h->scid));
}

static inline void echo_req(int level, l2cap_cmd_hdr *cmd, struct frame *frm)
{
	if (p_filter(FILT_L2CAP))
		return;

	printf("Echo req: dlen %d\n", btohs(cmd->len));
	raw_dump(level, frm);
}

static inline void echo_rsp(int level, l2cap_cmd_hdr *cmd, struct frame *frm)
{
	if (p_filter(FILT_L2CAP))
		return;

	printf("Echo rsp: dlen %d\n", btohs(cmd->len));
	raw_dump(level, frm);
}

static void info_opt(int level, int type, void *ptr, int len)
{
	uint32_t mask;

	p_indent(level, 0);

	switch (type) {
	case 0x0001:
		printf("Connectionless MTU %d\n", get_val(ptr, len));
		break;
	case 0x0002:
		mask = get_val(ptr, len);
		printf("Extended feature mask 0x%4.4x\n", mask);
		if (parser.flags & DUMP_VERBOSE) {
			if (mask & 0x01) {
				p_indent(level + 1, 0);
				printf("Flow control mode\n");
			}
			if (mask & 0x02) {
				p_indent(level + 1, 0);
				printf("Retransmission mode\n");
			}
			if (mask & 0x04) {
				p_indent(level + 1, 0);
				printf("Bi-directional QoS\n");
			}
		}
		break;
	case 0x0003:
		printf("Fixed channel list\n");
		break;
	default:
		printf("Unknown (len %d)\n", len);
		break;
	}
}

static inline void info_req(int level, l2cap_cmd_hdr *cmd, struct frame *frm)
{
	l2cap_info_req *h = frm->ptr;

	if (p_filter(FILT_L2CAP))
		return;

	printf("Info req: type %d\n", btohs(h->type));
}

static inline void info_rsp(int level, l2cap_cmd_hdr *cmd, struct frame *frm)
{
	l2cap_info_rsp *h = frm->ptr;
	uint16_t type = btohs(h->type);
	uint16_t result = btohs(h->result);
	int ilen = btohs(cmd->len) - L2CAP_INFO_RSP_SIZE;

	if (p_filter(FILT_L2CAP))
		return;

	printf("Info rsp: type %d result %d\n", type, result);

	if (ilen > 0) {
		info_opt(level + 1, type, h->data, ilen);
	} else {
		p_indent(level + 1, frm);
		printf("%s\n", inforesult2str(result));
	}
}

static void l2cap_parse(int level, struct frame *frm)
{
	l2cap_hdr *hdr = (void *)frm->ptr;
	uint16_t dlen = btohs(hdr->len);
	uint16_t cid  = btohs(hdr->cid);
	uint16_t psm;

	frm->ptr += L2CAP_HDR_SIZE;
	frm->len -= L2CAP_HDR_SIZE;

	if (cid == 0x1) {
		/* Signaling channel */

		while (frm->len >= L2CAP_CMD_HDR_SIZE) {
			l2cap_cmd_hdr *hdr = frm->ptr;

			frm->ptr += L2CAP_CMD_HDR_SIZE;
			frm->len -= L2CAP_CMD_HDR_SIZE;

			if (!p_filter(FILT_L2CAP)) {
				p_indent(level, frm);
				printf("L2CAP(s): ");
			}

			switch (hdr->code) {
			case L2CAP_COMMAND_REJ:
				command_rej(level, frm);
				break;
			
			case L2CAP_CONN_REQ:
				conn_req(level, frm);
				break;
	
			case L2CAP_CONN_RSP:
				conn_rsp(level, frm);
				break;

			case L2CAP_CONF_REQ:
				conf_req(level, hdr, frm);
				break;

			case L2CAP_CONF_RSP:
				conf_rsp(level, hdr, frm);
				break;

			case L2CAP_DISCONN_REQ:
				disconn_req(level, frm);
				break;

			case L2CAP_DISCONN_RSP:
				disconn_rsp(level, frm);
				break;
	
			case L2CAP_ECHO_REQ:
				echo_req(level, hdr, frm);
				break;

			case L2CAP_ECHO_RSP:
				echo_rsp(level, hdr, frm);
				break;

			case L2CAP_INFO_REQ:
				info_req(level, hdr, frm);
				break;

			case L2CAP_INFO_RSP:
				info_rsp(level, hdr, frm);
				break;

			default:
				if (p_filter(FILT_L2CAP))
					break;
				printf("code 0x%2.2x ident %d len %d\n", 
					hdr->code, hdr->ident, btohs(hdr->len));
				raw_dump(level, frm);
			}

			if (frm->len > btohs(hdr->len)) {
				frm->len -= btohs(hdr->len);
				frm->ptr += btohs(hdr->len);
			} else
				frm->len = 0;
		}
	} else if (cid == 0x2) {
		/* Connectionless channel */

		if (p_filter(FILT_L2CAP))
			return;

		psm = btohs(bt_get_unaligned((uint16_t *) frm->ptr));
		frm->ptr += 2;
		frm->len -= 2;

		p_indent(level, frm);
		printf("L2CAP(c): len %d psm %d\n", dlen, psm);
		raw_dump(level, frm);
	} else {
		/* Connection oriented channel */

		uint8_t mode = get_mode(!frm->in, cid);
		uint16_t psm = get_psm(!frm->in, cid);
		uint16_t ctrl = 0, fcs = 0;
		uint32_t proto;

		frm->cid = cid;
		frm->num = get_num(!frm->in, cid);

		if (mode > 0) {
			ctrl = btohs(bt_get_unaligned((uint16_t *) frm->ptr));
			frm->ptr += 2;
			frm->len -= 4;
			fcs = btohs(bt_get_unaligned((uint16_t *) (frm->ptr + frm->len)));
		}

		if (!p_filter(FILT_L2CAP)) {
			p_indent(level, frm);
			printf("L2CAP(d): cid 0x%4.4x len %d", cid, dlen);
			if (mode > 0)
				printf(" ctrl 0x%4.4x fcs 0x%4.4x", ctrl, fcs);
			printf(" [psm %d]\n", psm);
			level++;
			if (mode > 0) {
				p_indent(level, frm);
				printf("%s:", ctrl & 0x01 ? "S-frame" : "I-frame");
				if (ctrl & 0x01) {
					printf(" %s", supervisory2str((ctrl & 0x0c) >> 2));
				} else {
					uint8_t sar = (ctrl & 0xc000) >> 14;
					printf(" %s", sar2str(sar));
					if (sar == 1) {
						uint16_t len;
						len = btohs(bt_get_unaligned((uint16_t *) frm->ptr));
						frm->ptr += 2;
						frm->len -= 2;
						printf(" (len %d)", len);
					}
					printf(" TxSeq %d", (ctrl & 0x7e) >> 1);
				}
				printf(" ReqSeq %d", (ctrl & 0x3f00) >> 8);
				if (ctrl & 0x80)
					printf(" F-bit");
				if (ctrl & 0x10)
					printf(" P-bit");
				printf("\n");
			}
		}

		switch (psm) {
		case 0x01:
			if (!p_filter(FILT_SDP))
				sdp_dump(level + 1, frm);
			else
				raw_dump(level + 1, frm);
			break;

		case 0x03:
			if (!p_filter(FILT_RFCOMM))
				rfcomm_dump(level, frm);
			else
				raw_dump(level + 1, frm);
			break;

		case 0x0f:
			if (!p_filter(FILT_BNEP))
				bnep_dump(level, frm);
			else
				raw_dump(level + 1, frm);
			break;

		case 0x11:
		case 0x13:
			if (!p_filter(FILT_HIDP))
				hidp_dump(level, frm);
			else
				raw_dump(level + 1, frm);
			break;

		case 0x17:
			if (!p_filter(FILT_AVCTP))
				avctp_dump(level, frm);
			else
				raw_dump(level + 1, frm);
			break;

		case 0x19:
			if (!p_filter(FILT_AVDTP))
				avdtp_dump(level, frm);
			else
				raw_dump(level + 1, frm);
			break;

		case 0x1f:
			if (!p_filter(FILT_ATT))
				att_dump(level, frm);
			else
				raw_dump(level + 1, frm);
			break;

		default:
			proto = get_proto(frm->handle, psm, 0);

			switch (proto) {
			case SDP_UUID_CMTP:
				if (!p_filter(FILT_CMTP))
					cmtp_dump(level, frm);
				else
					raw_dump(level + 1, frm);
				break;

			case SDP_UUID_HARDCOPY_CONTROL_CHANNEL:
				if (!p_filter(FILT_HCRP))
					hcrp_dump(level, frm);
				else
					raw_dump(level + 1, frm);
				break;

			default:
				if (p_filter(FILT_L2CAP))
					break;

				raw_dump(level, frm);
				break;
			}
			break;
		}
	}
}

void l2cap_dump(int level, struct frame *frm)
{
	struct frame *fr;
	l2cap_hdr *hdr;
	uint16_t dlen;

	if ((frm->flags & ACL_START) || frm->flags == ACL_START_NO_FLUSH) {
		hdr  = frm->ptr;
		dlen = btohs(hdr->len);

		if ((int) frm->len == (dlen + L2CAP_HDR_SIZE)) {
			/* Complete frame */
			l2cap_parse(level, frm);
			return;
		}

		if (!(fr = get_frame(frm->handle))) {
			fprintf(stderr, "Not enough connection handles\n");
			raw_dump(level, frm);
			return;
		}

		if (fr->data)
			free(fr->data);

		if (!(fr->data = malloc(dlen + L2CAP_HDR_SIZE))) {
			perror("Can't allocate L2CAP reassembly buffer");
			return;
		}
		memcpy(fr->data, frm->ptr, frm->len);
		fr->data_len   = dlen + L2CAP_HDR_SIZE;
		fr->len        = frm->len;
		fr->ptr        = fr->data;
		fr->dev_id     = frm->dev_id;
		fr->in         = frm->in;
		fr->ts         = frm->ts;
		fr->handle     = frm->handle;
		fr->cid        = frm->cid;
		fr->num        = frm->num;
		fr->dlci       = frm->dlci;
		fr->channel    = frm->channel;
		fr->pppdump_fd = frm->pppdump_fd;
		fr->audio_fd   = frm->audio_fd;
	} else {
		if (!(fr = get_frame(frm->handle))) {
			fprintf(stderr, "Not enough connection handles\n");
			raw_dump(level, frm);
			return;
		}

		if (!fr->data) {
			/* Unexpected fragment */
			raw_dump(level, frm);
			return;
		}

		if (frm->len > (fr->data_len - fr->len)) {
			/* Bad fragment */
			raw_dump(level, frm);
			free(fr->data); fr->data = NULL;
			return;
		}

		memcpy(fr->data + fr->len, frm->ptr, frm->len);
		fr->len += frm->len;

		if (fr->len == fr->data_len) {
			/* Complete frame */
			l2cap_parse(level, fr);

			free(fr->data); fr->data = NULL;
			return;
		}
	}
}

void l2cap_clear(uint16_t handle)
{
	del_handle(handle);
}
