/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2011-2014  Intel Corporation
 *  Copyright (C) 2002-2010  Marcel Holtmann <marcel@holtmann.org>
 *
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; 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 <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <inttypes.h>

#include "lib/bluetooth.h"
#include "lib/uuid.h"

#include "src/shared/util.h"
#include "bt.h"
#include "packet.h"
#include "display.h"
#include "l2cap.h"
#include "keys.h"
#include "sdp.h"
#include "rfcomm.h"

static char *cr_str[] = {
	"RSP",
	"CMD"
};

/* RFCOMM frame parsing macros */
#define CR_STR(type)		cr_str[GET_CR(type)]
#define GET_LEN8(length)	((length & 0xfe) >> 1)
#define GET_LEN16(length)	((length & 0xfffe) >> 1)
#define GET_CR(type)		((type & 0x02) >> 1)
#define GET_PF(ctr)		(((ctr) >> 4) & 0x1)

/* MSC macros */
#define GET_V24_FC(sigs)	((sigs & 0x02) >> 1)
#define GET_V24_RTC(sigs)	((sigs & 0x04) >> 2)
#define GET_V24_RTR(sigs)	((sigs & 0x08) >> 3)
#define GET_V24_IC(sigs)	((sigs & 0x40) >> 6)
#define GET_V24_DV(sigs)	((sigs & 0x80) >> 7)

/* RPN macros */
#define GET_RPN_DB(parity)	(parity & 0x03)
#define GET_RPN_SB(parity)	((parity & 0x04) >> 2)
#define GET_RPN_PARITY(parity)	((parity & 0x08) >> 3)
#define GET_RPN_PTYPE(parity)	((parity & 0x30) >> 4)
#define GET_RPN_XIN(io)		(io & 0x01)
#define GET_RPN_XOUT(io)	((io & 0x02) >> 1)
#define GET_RPN_RTRI(io)	((io & 0x04) >> 2)
#define GET_RPN_RTRO(io)	((io & 0x08) >> 3)
#define GET_RPN_RTCI(io)	((io & 0x10) >> 4)
#define GET_RPN_RTCO(io)	((io & 0x20) >> 5)

/* RLS macro */
#define GET_ERROR(err)		(err & 0x0f)

/* PN macros */
#define GET_FRM_TYPE(ctrl)	((ctrl & 0x0f))
#define GET_CRT_FLOW(ctrl)	((ctrl & 0xf0) >> 4)
#define GET_PRIORITY(prio)	((prio & 0x3f))
#define GET_PN_DLCI(dlci)	((dlci & 0x3f))

struct rfcomm_lhdr {
	uint8_t address;
	uint8_t control;
	uint16_t length;
	uint8_t fcs;
	uint8_t credits; /* only for UIH frame */
};

struct rfcomm_lmsc {
	uint8_t dlci;
	uint8_t v24_sig;
	uint8_t break_sig;
};

struct rfcomm_rpn {
	uint8_t dlci;
	uint8_t bit_rate;
	uint8_t parity;
	uint8_t io;
	uint8_t xon;
	uint8_t xoff;
	uint16_t pm;
};

struct rfcomm_rls {
	uint8_t dlci;
	uint8_t error;
};

struct rfcomm_nsc {
	uint8_t cmd_type;
};

struct rfcomm_lmcc {
	uint8_t type;
	uint16_t length;
};

struct rfcomm_frame {
	struct rfcomm_lhdr hdr;
	struct rfcomm_lmcc mcc;
	struct l2cap_frame l2cap_frame;
};

static void print_rfcomm_hdr(struct rfcomm_frame *rfcomm_frame, uint8_t indent)
{
	struct rfcomm_lhdr hdr = rfcomm_frame->hdr;

	/* Address field */
	print_field("%*cAddress: 0x%2.2x cr %d dlci 0x%2.2x", indent, ' ',
					hdr.address, GET_CR(hdr.address),
					RFCOMM_GET_DLCI(hdr.address));

	/* Control field */
	print_field("%*cControl: 0x%2.2x poll/final %d", indent, ' ',
					hdr.control, GET_PF(hdr.control));

	/* Length and FCS */
	print_field("%*cLength: %d", indent, ' ', hdr.length);
	print_field("%*cFCS: 0x%2.2x", indent, ' ', hdr.fcs);
}

static inline bool mcc_test(struct rfcomm_frame *rfcomm_frame, uint8_t indent)
{
	struct l2cap_frame *frame = &rfcomm_frame->l2cap_frame;
	uint8_t data;

	printf("%*cTest Data: 0x ", indent, ' ');

	while (frame->size > 1) {
		if (!l2cap_frame_get_u8(frame, &data))
			return false;
		printf("%2.2x ", data);
	}

	printf("\n");
	return true;
}

static inline bool mcc_msc(struct rfcomm_frame *rfcomm_frame, uint8_t indent)
{
	struct l2cap_frame *frame = &rfcomm_frame->l2cap_frame;
	struct rfcomm_lmsc msc;

	if (!l2cap_frame_get_u8(frame, &msc.dlci))
		return false;

	print_field("%*cdlci %d ", indent, ' ', RFCOMM_GET_DLCI(msc.dlci));

	if (!l2cap_frame_get_u8(frame, &msc.v24_sig))
		return false;

	/* v24 control signals */
	print_field("%*cfc %d rtc %d rtr %d ic %d dv %d", indent, ' ',
		GET_V24_FC(msc.v24_sig), GET_V24_RTC(msc.v24_sig),
		GET_V24_RTR(msc.v24_sig), GET_V24_IC(msc.v24_sig),
					GET_V24_DV(msc.v24_sig));

	if (frame->size < 2)
		goto done;

	/*
	 * TODO: Implement the break signals decoding.
	 */

	packet_hexdump(frame->data, frame->size);

done:
	return true;
}

static inline bool mcc_rpn(struct rfcomm_frame *rfcomm_frame, uint8_t indent)
{
	struct l2cap_frame *frame = &rfcomm_frame->l2cap_frame;
	struct rfcomm_rpn rpn;

	if (!l2cap_frame_get_u8(frame, &rpn.dlci))
		return false;

	print_field("%*cdlci %d", indent, ' ', RFCOMM_GET_DLCI(rpn.dlci));

	if (frame->size < 7)
		goto done;

	/* port value octets (optional) */

	if (!l2cap_frame_get_u8(frame, &rpn.bit_rate))
		return false;

	if (!l2cap_frame_get_u8(frame, &rpn.parity))
		return false;

	if (!l2cap_frame_get_u8(frame, &rpn.io))
		return false;

	print_field("%*cbr %d db %d sb %d p %d pt %d xi %d xo %d", indent, ' ',
		rpn.bit_rate, GET_RPN_DB(rpn.parity), GET_RPN_SB(rpn.parity),
		GET_RPN_PARITY(rpn.parity), GET_RPN_PTYPE(rpn.parity),
		GET_RPN_XIN(rpn.io), GET_RPN_XOUT(rpn.io));

	if (!l2cap_frame_get_u8(frame, &rpn.xon))
		return false;

	if (!l2cap_frame_get_u8(frame, &rpn.xoff))
		return false;

	print_field("%*crtri %d rtro %d rtci %d rtco %d xon %d xoff %d",
		indent, ' ', GET_RPN_RTRI(rpn.io), GET_RPN_RTRO(rpn.io),
		GET_RPN_RTCI(rpn.io), GET_RPN_RTCO(rpn.io), rpn.xon,
		rpn.xoff);

	if (!l2cap_frame_get_le16(frame, &rpn.pm))
		return false;

	print_field("%*cpm 0x%04x", indent, ' ', rpn.pm);

done:
	return true;
}

static inline bool mcc_rls(struct rfcomm_frame *rfcomm_frame, uint8_t indent)
{
	struct l2cap_frame *frame = &rfcomm_frame->l2cap_frame;
	struct rfcomm_rls rls;

	if (!l2cap_frame_get_u8(frame, &rls.dlci))
		return false;

	if (!l2cap_frame_get_u8(frame, &rls.error))
		return false;

	print_field("%*cdlci %d error: %d", indent, ' ',
			RFCOMM_GET_DLCI(rls.dlci), GET_ERROR(rls.error));

	return true;
}

static inline bool mcc_pn(struct rfcomm_frame *rfcomm_frame, uint8_t indent)
{
	struct l2cap_frame *frame = &rfcomm_frame->l2cap_frame;
	struct rfcomm_pn pn;
	uint16_t mtu;

	/* rfcomm_pn struct is defined in rfcomm.h */

	if (!l2cap_frame_get_u8(frame, &pn.dlci))
		return false;

	if (!l2cap_frame_get_u8(frame, &pn.flow_ctrl))
		return false;

	if (!l2cap_frame_get_u8(frame, &pn.priority))
		return false;

	print_field("%*cdlci %d frame_type %d credit_flow %d pri %d", indent,
			' ', GET_PN_DLCI(pn.dlci), GET_FRM_TYPE(pn.flow_ctrl),
			GET_CRT_FLOW(pn.flow_ctrl), GET_PRIORITY(pn.priority));

	if (!l2cap_frame_get_u8(frame, &pn.ack_timer))
		return false;

	if (!l2cap_frame_get_le16(frame, &mtu))
		return false;

	pn.mtu = mtu;

	if (!l2cap_frame_get_u8(frame, &pn.max_retrans))
		return false;

	if (!l2cap_frame_get_u8(frame, &pn.credits))
		return false;

	print_field("%*cack_timer %d frame_size %d max_retrans %d credits %d",
			indent, ' ', pn.ack_timer, pn.mtu, pn.max_retrans,
			pn.credits);

	return true;
}

static inline bool mcc_nsc(struct rfcomm_frame *rfcomm_frame, uint8_t indent)
{
	struct l2cap_frame *frame = &rfcomm_frame->l2cap_frame;
	struct rfcomm_nsc nsc;

	if (!l2cap_frame_get_u8(frame, &nsc.cmd_type))
		return false;

	print_field("%*ccr %d, mcc_cmd_type %x", indent, ' ',
		GET_CR(nsc.cmd_type), RFCOMM_GET_MCC_TYPE(nsc.cmd_type));

	return true;
}

struct mcc_data {
	uint8_t type;
	const char *str;
};

static const struct mcc_data mcc_table[] = {
	{ 0x08, "Test Command" },
	{ 0x28, "Flow Control On Command" },
	{ 0x18, "Flow Control Off Command" },
	{ 0x38, "Modem Status Command" },
	{ 0x24, "Remote Port Negotiation Command" },
	{ 0x14, "Remote Line Status" },
	{ 0x20, "DLC Parameter Negotiation" },
	{ 0x04, "Non Supported Command" },
	{ }
};

static inline bool mcc_frame(struct rfcomm_frame *rfcomm_frame, uint8_t indent)
{
	uint8_t length, ex_length, type;
	const char *type_str;
	int i;
	struct l2cap_frame *frame = &rfcomm_frame->l2cap_frame;
	struct rfcomm_lmcc mcc;
	const struct mcc_data *mcc_data = NULL;

	if (!l2cap_frame_get_u8(frame, &mcc.type) ||
			!l2cap_frame_get_u8(frame, &length))
		return false;

	if (RFCOMM_TEST_EA(length))
		mcc.length = (uint16_t) GET_LEN8(length);
	else {
		if (!l2cap_frame_get_u8(frame, &ex_length))
			return false;
		mcc.length = ((uint16_t) length << 8) | ex_length;
		mcc.length = GET_LEN16(mcc.length);
	}

	type = RFCOMM_GET_MCC_TYPE(mcc.type);

	for (i = 0; mcc_table[i].str; i++) {
		if (mcc_table[i].type == type) {
			mcc_data = &mcc_table[i];
			break;
		}
	}

	if (mcc_data)
		type_str = mcc_data->str;
	else
		type_str = "Unknown";

	print_field("%*cMCC Message type: %s %s (0x%2.2x)", indent, ' ',
				type_str, CR_STR(mcc.type), type);

	print_field("%*cLength: %d", indent+2, ' ', mcc.length);

	rfcomm_frame->mcc = mcc;

	switch (type) {
	case RFCOMM_TEST:
		return mcc_test(rfcomm_frame, indent+10);
	case RFCOMM_MSC:
		return mcc_msc(rfcomm_frame, indent+2);
	case RFCOMM_RPN:
		return mcc_rpn(rfcomm_frame, indent+2);
	case RFCOMM_RLS:
		return mcc_rls(rfcomm_frame, indent+2);
	case RFCOMM_PN:
		return mcc_pn(rfcomm_frame, indent+2);
	case RFCOMM_NSC:
		return mcc_nsc(rfcomm_frame, indent+2);
	default:
		packet_hexdump(frame->data, frame->size);
	}

	return true;
}

static bool uih_frame(struct rfcomm_frame *rfcomm_frame, uint8_t indent)
{
	uint8_t credits;
	struct l2cap_frame *frame = &rfcomm_frame->l2cap_frame;
	struct rfcomm_lhdr *hdr = &rfcomm_frame->hdr;

	if (!RFCOMM_GET_CHANNEL(hdr->address))
		return mcc_frame(rfcomm_frame, indent);

	/* fetching credits from UIH frame */
	if (GET_PF(hdr->control)) {
		if (!l2cap_frame_get_u8(frame, &credits))
			return false;
		hdr->credits = credits;
		print_field("%*cCredits: %d", indent, ' ', hdr->credits);
	}

	packet_hexdump(frame->data, frame->size);
	return true;
}

struct rfcomm_data {
	uint8_t frame;
	const char *str;
};

static const struct rfcomm_data rfcomm_table[] = {
	{ 0x2f, "Set Async Balance Mode (SABM)" },
	{ 0x63, "Unnumbered Ack (UA)" },
	{ 0x0f, "Disconnect Mode (DM)" },
	{ 0x43, "Disconnect (DISC)" },
	{ 0xef, "Unnumbered Info with Header Check (UIH)" },
	{ }
};

void rfcomm_packet(const struct l2cap_frame *frame)
{
	uint8_t ctype, length, ex_length, indent = 1;
	const char *frame_str, *frame_color;
	struct l2cap_frame *l2cap_frame, tmp_frame;
	struct rfcomm_frame rfcomm_frame;
	struct rfcomm_lhdr hdr;
	const struct rfcomm_data *rfcomm_data = NULL;
	int i;

	l2cap_frame_pull(&rfcomm_frame.l2cap_frame, frame, 0);

	l2cap_frame = &rfcomm_frame.l2cap_frame;

	if (frame->size < 4)
		goto fail;

	if (!l2cap_frame_get_u8(l2cap_frame, &hdr.address) ||
			!l2cap_frame_get_u8(l2cap_frame, &hdr.control) ||
			!l2cap_frame_get_u8(l2cap_frame, &length))
		goto fail;

	/* length maybe 1 or 2 octets */
	if (RFCOMM_TEST_EA(length))
		hdr.length = (uint16_t) GET_LEN8(length);
	else {
		if (!l2cap_frame_get_u8(l2cap_frame, &ex_length))
			goto fail;
		hdr.length = ((uint16_t)length << 8) | ex_length;
		hdr.length = GET_LEN16(hdr.length);
	}

	l2cap_frame_pull(&tmp_frame, l2cap_frame, l2cap_frame->size-1);

	if (!l2cap_frame_get_u8(&tmp_frame, &hdr.fcs))
		goto fail;

	/* Decoding frame type */
	ctype = RFCOMM_GET_TYPE(hdr.control);

	for (i = 0; rfcomm_table[i].str; i++) {
		if (rfcomm_table[i].frame == ctype) {
			rfcomm_data = &rfcomm_table[i];
			break;
		}
	}

	if (rfcomm_data) {
		if (frame->in)
			frame_color = COLOR_MAGENTA;
		else
			frame_color = COLOR_BLUE;
		frame_str = rfcomm_data->str;
	} else {
		frame_color = COLOR_WHITE_BG;
		frame_str = "Unknown";
	}

	if (!rfcomm_data) {
		packet_hexdump(frame->data, frame->size);
		return;
	}

	print_indent(6, frame_color, "RFCOMM: ", frame_str, COLOR_OFF,
						" (0x%2.2x)", ctype);

	rfcomm_frame.hdr = hdr;
	print_rfcomm_hdr(&rfcomm_frame, indent);

	/* UIH frame */
	if (ctype == 0xef)
		if (!uih_frame(&rfcomm_frame, indent))
			goto fail;

	return;

fail:
	print_text(COLOR_ERROR, "Frame too short");
	packet_hexdump(frame->data, frame->size);
	return;
}
