/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2001-2002  Wayne Lee <waynelee@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 "parser.h"
#include "rfcomm.h"
#include "sdp.h"

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

#define CR_STR(mcc_head) cr_str[mcc_head->type.cr]
#define GET_DLCI(addr) ((addr.server_chn << 1) | (addr.d & 1))

static void print_rfcomm_hdr(long_frame_head* head, uint8_t *ptr, int len)
{
	address_field addr = head->addr;
	uint8_t ctr = head->control;
	uint16_t ilen = head->length.bits.len;
	uint8_t ctr_type,pf,dlci,fcs;

	dlci     = GET_DLCI(addr);
	pf       = GET_PF(ctr);
	ctr_type = CLR_PF(ctr);
	fcs      = *(ptr + len - 1);

	printf("cr %d dlci %d pf %d ilen %d fcs 0x%x ", addr.cr, dlci, pf, ilen, fcs); 
}

static void print_mcc(mcc_long_frame_head* mcc_head)
{
	printf("mcc_len %d\n", mcc_head->length.bits.len);
}

static inline void mcc_test(int level, uint8_t *ptr, int len,
				long_frame_head *head, mcc_long_frame_head *mcc_head)
{
	printf("TEST %s: ", CR_STR(mcc_head));
	print_rfcomm_hdr(head, ptr, len);
	print_mcc(mcc_head);
}
static inline void mcc_fcon(int level, uint8_t *ptr, int len,
				long_frame_head *head, mcc_long_frame_head *mcc_head)
{
	printf("FCON %s: ", CR_STR(mcc_head));
	print_rfcomm_hdr(head, ptr, len);
	print_mcc(mcc_head);
}

static inline void mcc_fcoff(int level, uint8_t *ptr, int len,
				long_frame_head *head, mcc_long_frame_head *mcc_head)
{
	printf("FCOFF %s: ", CR_STR(mcc_head));
	print_rfcomm_hdr(head, ptr, len);
	print_mcc(mcc_head);
}

static inline void mcc_msc(int level, uint8_t *ptr, unsigned int len,
				long_frame_head *head, mcc_long_frame_head *mcc_head)
{
	msc_msg *msc = (void*) (ptr - STRUCT_END(msc_msg, mcc_s_head));

	printf("MSC %s: ", CR_STR(mcc_head));
	print_rfcomm_hdr(head, ptr, len);
	print_mcc(mcc_head);
	p_indent(level, 0);
	printf("dlci %d fc %d rtc %d rtr %d ic %d dv %d",
		GET_DLCI(msc->dlci), msc->v24_sigs.fc, msc->v24_sigs.rtc, 
		msc->v24_sigs.rtr, msc->v24_sigs.ic, msc->v24_sigs.dv );

	/* Assuming that break_signals field is _not declared_ in struct msc_msg... */
	if (len > STRUCT_OFFSET(msc_msg, fcs) - STRUCT_END(msc_msg, v24_sigs)) {
		break_signals *brk = (break_signals *)
			(ptr + STRUCT_END(msc_msg, v24_sigs));
		printf(" b1 %d b2 %d b3 %d len %d\n",
			brk->b1, brk->b2, brk->b3, brk->len);
	} else
		printf("\n");
}

static inline void mcc_rpn(int level, uint8_t *ptr, unsigned int len,
				long_frame_head *head, mcc_long_frame_head *mcc_head)
{
	rpn_msg *rpn = (void *) (ptr - STRUCT_END(rpn_msg, mcc_s_head));

	printf("RPN %s: ", CR_STR(mcc_head));
	print_rfcomm_hdr(head, ptr, len);
	print_mcc(mcc_head);

	p_indent(level, 0);
	printf("dlci %d ", GET_DLCI(rpn->dlci));

	/* Assuming that rpn_val is _declared_ as a member of rpn_msg... */
	if (len <= STRUCT_OFFSET(rpn_msg, rpn_val) - STRUCT_END(rpn_msg, mcc_s_head)) {
		printf("\n");
		return;
	}

	printf("br %d db %d sb %d p %d pt %d xi %d xo %d\n",
		rpn->rpn_val.bit_rate, rpn->rpn_val.data_bits, 
		rpn->rpn_val.stop_bit, rpn->rpn_val.parity,
		rpn->rpn_val.parity_type, rpn->rpn_val.xon_input,
		rpn->rpn_val.xon_output);

	p_indent(level, 0);
	printf("rtri %d rtro %d rtci %d rtco %d xon %d xoff %d pm 0x%04x\n",
		rpn->rpn_val.rtr_input, rpn->rpn_val.rtr_output,
		rpn->rpn_val.rtc_input, rpn->rpn_val.rtc_output,
		rpn->rpn_val.xon, rpn->rpn_val.xoff, btohs(rpn->rpn_val.pm));
}

static inline void mcc_rls(int level, uint8_t *ptr, int len,
				long_frame_head *head, mcc_long_frame_head *mcc_head)
{
	rls_msg* rls = (void*) (ptr - STRUCT_END(rls_msg, mcc_s_head));

	printf("RLS %s: ", CR_STR(mcc_head));
	print_rfcomm_hdr(head, ptr, len);
	print_mcc(mcc_head);
	printf("dlci %d error: %d", GET_DLCI(rls->dlci), rls->error);
}

static inline void mcc_pn(int level, uint8_t *ptr, int len,
				long_frame_head *head, mcc_long_frame_head *mcc_head)
{
	pn_msg *pn = (void*) (ptr - STRUCT_END(pn_msg, mcc_s_head));

	printf("PN %s: ", CR_STR(mcc_head));
	print_rfcomm_hdr(head, ptr, len);
	print_mcc(mcc_head);

	p_indent(level, 0);
	printf("dlci %d frame_type %d credit_flow %d pri %d ack_timer %d\n",
		pn->dlci, pn->frame_type, pn->credit_flow, pn->prior, pn->ack_timer);
	p_indent(level, 0);
	printf("frame_size %d max_retrans %d credits %d\n",
		btohs(pn->frame_size), pn->max_nbrof_retrans, pn->credits);
}

static inline void mcc_nsc(int level, uint8_t *ptr, int len,
				long_frame_head *head, mcc_long_frame_head *mcc_head)
{

	nsc_msg *nsc = (void*) (ptr - STRUCT_END(nsc_msg, mcc_s_head));

	printf("NSC %s: ", CR_STR(mcc_head));
	print_rfcomm_hdr(head, ptr, len);
	print_mcc(mcc_head);

	p_indent(level, 0);
	printf("cr %d, mcc_cmd_type %x\n", 
		nsc->command_type.cr, nsc->command_type.type );
}

static inline void mcc_frame(int level, struct frame *frm, long_frame_head *head)
{
	mcc_short_frame_head *mcc_short_head_p = frm->ptr;
	mcc_long_frame_head mcc_head;
	uint8_t hdr_size;

	if ( mcc_short_head_p->length.ea == EA ) {
		mcc_head.type = mcc_short_head_p->type;
		mcc_head.length.bits.len = mcc_short_head_p->length.len;
		hdr_size = sizeof(mcc_short_frame_head);
	} else {
		mcc_head = *(mcc_long_frame_head *)frm->ptr;
		mcc_head.length.val = btohs(mcc_head.length.val);
		hdr_size = sizeof(mcc_long_frame_head);
	}

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

	p_indent(level, frm);
	printf("RFCOMM(s): ");

	switch (mcc_head.type.type) {
	case TEST:
		mcc_test(level, frm->ptr, frm->len, head, &mcc_head);
		raw_dump(level, frm); 
		break;
	case FCON:
		mcc_fcon(level, frm->ptr, frm->len, head, &mcc_head);
		break;
	case FCOFF:
		mcc_fcoff(level, frm->ptr, frm->len, head, &mcc_head);
		break;
	case MSC:
		mcc_msc(level, frm->ptr, frm->len, head, &mcc_head);
		break;
	case RPN:
		mcc_rpn(level, frm->ptr, frm->len, head, &mcc_head);
		break;
	case RLS:
		mcc_rls(level, frm->ptr, frm->len, head, &mcc_head);
		break;
	case PN:
		mcc_pn(level, frm->ptr, frm->len, head, &mcc_head);
		break;
	case NSC:
		mcc_nsc(level, frm->ptr, frm->len, head, &mcc_head);
		break;
	default:
		printf("MCC message type 0x%02x: ", mcc_head.type.type);
		print_rfcomm_hdr(head, frm->ptr, frm->len);
		printf("\n");

		frm->len--;
		raw_dump(level, frm); 
	}
}

static inline void uih_frame(int level, struct frame *frm, long_frame_head *head)
{
	uint32_t proto;

	if (!head->addr.server_chn) {
		mcc_frame(level, frm, head); 
	} else {
		p_indent(level, frm);
		printf("RFCOMM(d): UIH: ");
		print_rfcomm_hdr(head, frm->ptr, frm->len);
		if (GET_PF(head->control)) {
			printf("credits %d\n", *(uint8_t *)(frm->ptr));
			frm->ptr++;
			frm->len--;
		} else
			printf("\n");

		frm->len--;
		frm->dlci = GET_DLCI(head->addr);
		frm->channel = head->addr.server_chn;

		proto = get_proto(frm->handle, RFCOMM_PSM, frm->channel);

		if (frm->len > 0) {
			switch (proto) {
			case SDP_UUID_OBEX:
				if (!p_filter(FILT_OBEX))
					obex_dump(level + 1, frm);
				else
					raw_dump(level, frm);
				break;

			case SDP_UUID_LAN_ACCESS_PPP:
			case SDP_UUID_DIALUP_NETWORKING:
				if (!p_filter(FILT_PPP))
					ppp_dump(level + 1, frm);
				else
					raw_dump(level, frm);
				break;

			default:
				if (p_filter(FILT_RFCOMM))
					break;

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

void rfcomm_dump(int level, struct frame *frm)
{
	uint8_t hdr_size, ctr_type;
	short_frame_head *short_head_p = (void *) frm->ptr;
	long_frame_head head;

	if (short_head_p->length.ea == EA) {
		head.addr = short_head_p->addr;
		head.control = short_head_p->control;
		head.length.bits.len = short_head_p->length.len;
		hdr_size = sizeof(short_frame_head);
	} else {
		head = *(long_frame_head *) frm->ptr;
		head.length.val = btohs(head.length.val);
		hdr_size = sizeof(long_frame_head);
	}

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

	ctr_type = CLR_PF(head.control);

	if (ctr_type == UIH) {
		uih_frame(level, frm, &head);
	} else {
		p_indent(level, frm); 
		printf("RFCOMM(s): ");

		switch (ctr_type) {
		case SABM:
			printf("SABM: ");
			break;
		case UA:
			printf("UA: ");
			break;
		case DM:
			printf("DM: ");
			break;
		case DISC:
			printf("DISC: ");
			del_frame(frm->handle, GET_DLCI(head.addr));
			break;
		default:
			printf("ERR: ");
		}
		print_rfcomm_hdr(&head, frm->ptr, frm->len);
		printf("\n");
	}
}
