/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2012 Intel Corporation. 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 St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

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

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <time.h>

#include "lib/bluetooth.h"
#include "lib/hci.h"
#include "lib/hci_lib.h"

#include "hciattach.h"

#ifdef INTEL_DEBUG
#define DBGPRINT(fmt, args...)	printf("DBG: " fmt "\n", ## args)
#define PRINT_PACKET(buf, len, msg)	{	\
	int i;					\
	printf("%s\n", msg);			\
	for (i = 0; i < len; i++)		\
		printf("%02X ", buf[i]);	\
	printf("\n");				\
	}
#else
#define DBGPRINT(fmt, args...)
#define PRINT_PACKET(buf, len, msg)
#endif

#define PATCH_SEQ_EXT           ".bseq"
#define PATCH_FILE_PATH         "/lib/firmware/intel/"
#define PATCH_MAX_LEN           260
#define PATCH_TYPE_CMD          1
#define PATCH_TYPE_EVT          2

#define INTEL_VER_PARAM_LEN     9
#define INTEL_MFG_PARAM_LEN     2

/**
 * A data structure for a patch entry.
 */
struct patch_entry {
	int type;
	int len;
	unsigned char data[PATCH_MAX_LEN];
};

/**
 * A structure for patch context
 */
struct patch_ctx {
	int dev;
	int fd;
	int patch_error;
	int reset_enable_patch;
};

/**
 * Send HCI command to the controller
 */
static int intel_write_cmd(int dev, unsigned char *buf, int len)
{
	int ret;

	PRINT_PACKET(buf, len, "<----- SEND CMD: ");

	ret = write(dev, buf, len);
	if (ret < 0)
		return -errno;

	if (ret != len)
		return -1;

	return ret;
}

/**
 * Read the event from the controller
 */
static int intel_read_evt(int dev, unsigned char *buf, int len)
{
	int ret;

	ret = read_hci_event(dev, buf, len);
	if (ret < 0)
		return -1;

	PRINT_PACKET(buf, ret, "-----> READ EVT: ");

	return ret;
}

/**
 * Validate HCI events
 */
static int validate_events(struct patch_entry *event,
		struct patch_entry *entry)
{
	if (event == NULL || entry == NULL) {
		DBGPRINT("invalid patch entry parameters");
		return -1;
	}

	if (event->len != entry->len) {
		DBGPRINT("lengths are mismatched:[%d|%d]",
				event->len, entry->len);
		return -1;
	}

	if (memcmp(event->data, entry->data, event->len)) {
		DBGPRINT("data is mismatched");
		return -1;
	}

	return 0;
}

/**
 * Read the next patch entry one line at a time
 */
static int get_next_patch_entry(int fd, struct patch_entry *entry)
{
	int size;
	char rb;

	if (read(fd, &rb, 1) <= 0)
		return 0;

	entry->type = rb;

	switch (entry->type) {
	case PATCH_TYPE_CMD:
		entry->data[0] = HCI_COMMAND_PKT;

		if (read(fd, &entry->data[1], 3) < 0)
			return -1;

		size = (int)entry->data[3];

		if (read(fd, &entry->data[4], size) < 0)
			return -1;

		entry->len = HCI_TYPE_LEN + HCI_COMMAND_HDR_SIZE + size;

		break;

	case PATCH_TYPE_EVT:
		entry->data[0] = HCI_EVENT_PKT;

		if (read(fd, &entry->data[1], 2) < 0)
			return -1;

		size = (int)entry->data[2];

		if (read(fd, &entry->data[3], size) < 0)
			return -1;

		entry->len = HCI_TYPE_LEN + HCI_EVENT_HDR_SIZE + size;

		break;

	default:
		fprintf(stderr, "invalid patch entry(%d)\n", entry->type);
		return -1;
	}

	return entry->len;
}

/**
 * Download the patch set to the controller and verify the event
 */
static int intel_download_patch(struct patch_ctx *ctx)
{
	int ret;
	struct patch_entry entry;
	struct patch_entry event;

	DBGPRINT("start patch downloading");

	do {
		ret = get_next_patch_entry(ctx->fd, &entry);
		if (ret <= 0) {
			ctx->patch_error = 1;
			break;
		}

		switch (entry.type) {
		case PATCH_TYPE_CMD:
			ret = intel_write_cmd(ctx->dev,
					entry.data,
					entry.len);
			if (ret <= 0) {
				fprintf(stderr, "failed to send cmd(%d)\n",
						ret);
				return ret;
			}
			break;

		case PATCH_TYPE_EVT:
			ret = intel_read_evt(ctx->dev, event.data,
					sizeof(event.data));
			if (ret <= 0) {
				fprintf(stderr, "failed to read evt(%d)\n",
						ret);
				return ret;
			}
			event.len = ret;

			if (validate_events(&event, &entry) < 0) {
				DBGPRINT("events are mismatched");
				ctx->patch_error = 1;
				return -1;
			}
			break;

		default:
			fprintf(stderr, "unknown patch type(%d)\n",
					entry.type);
			return -1;
		}
	} while (1);

	return ret;
}

static int open_patch_file(struct patch_ctx *ctx, char *fw_ver)
{
	char patch_file[PATH_MAX];

	snprintf(patch_file, PATH_MAX, "%s%s%s", PATCH_FILE_PATH,
			fw_ver, PATCH_SEQ_EXT);
	DBGPRINT("PATCH_FILE: %s", patch_file);

	ctx->fd = open(patch_file, O_RDONLY);
	if (ctx->fd < 0) {
		DBGPRINT("cannot open patch file. go to post patch");
		return -1;
	}

	return 0;
}

/**
 * Prepare the controller for patching.
 */
static int pre_patch(struct patch_ctx *ctx)
{
	int ret, i;
	struct patch_entry entry;
	char fw_ver[INTEL_VER_PARAM_LEN * 2];

	DBGPRINT("start pre_patch");

	entry.data[0] = HCI_COMMAND_PKT;
	entry.data[1] = 0x11;
	entry.data[2] = 0xFC;
	entry.data[3] = 0x02;
	entry.data[4] = 0x01;
	entry.data[5] = 0x00;
	entry.len = HCI_TYPE_LEN + HCI_COMMAND_HDR_SIZE + INTEL_MFG_PARAM_LEN;

	ret = intel_write_cmd(ctx->dev, entry.data, entry.len);
	if (ret < 0) {
		fprintf(stderr, "failed to send cmd(%d)\n", ret);
		return ret;
	}

	ret = intel_read_evt(ctx->dev, entry.data, sizeof(entry.data));
	if (ret < 0) {
		fprintf(stderr, "failed to read evt(%d)\n", ret);
		return ret;
	}
	entry.len = ret;

	if (entry.data[6] != 0x00) {
		DBGPRINT("command failed. status=%02x", entry.data[6]);
		ctx->patch_error = 1;
		return -1;
	}

	entry.data[0] = HCI_COMMAND_PKT;
	entry.data[1] = 0x05;
	entry.data[2] = 0xFC;
	entry.data[3] = 0x00;
	entry.len = HCI_TYPE_LEN + HCI_COMMAND_HDR_SIZE;

	ret = intel_write_cmd(ctx->dev, entry.data, entry.len);
	if (ret < 0) {
		fprintf(stderr, "failed to send cmd(%d)\n", ret);
		return ret;
	}

	ret = intel_read_evt(ctx->dev, entry.data, sizeof(entry.data));
	if (ret < 0) {
		fprintf(stderr, "failed to read evt(%d)\n", ret);
		return ret;
	}
	entry.len = ret;

	if (entry.data[6] != 0x00) {
		DBGPRINT("command failed. status=%02x", entry.data[6]);
		ctx->patch_error = 1;
		return -1;
	}

	for (i = 0; i < INTEL_VER_PARAM_LEN; i++)
		sprintf(&fw_ver[i*2], "%02x", entry.data[7+i]);

	if (open_patch_file(ctx, fw_ver) < 0) {
		ctx->patch_error = 1;
		return -1;
	}

	return ret;
}

/*
 * check the event is startup event
 */
static int is_startup_evt(unsigned char *buf)
{
	if (buf[1] == 0xFF && buf[2] == 0x01 && buf[3] == 0x00)
		return 1;

	return 0;
}

/**
 * Finalize the patch process and reset the controller
 */
static int post_patch(struct patch_ctx *ctx)
{
	int ret;
	struct patch_entry entry;

	DBGPRINT("start post_patch");

	entry.data[0] = HCI_COMMAND_PKT;
	entry.data[1] = 0x11;
	entry.data[2] = 0xFC;
	entry.data[3] = 0x02;
	entry.data[4] = 0x00;
	if (ctx->reset_enable_patch)
		entry.data[5] = 0x02;
	else
		entry.data[5] = 0x01;

	entry.len = HCI_TYPE_LEN + HCI_COMMAND_HDR_SIZE + INTEL_MFG_PARAM_LEN;

	ret = intel_write_cmd(ctx->dev, entry.data, entry.len);
	if (ret < 0) {
		fprintf(stderr, "failed to send cmd(%d)\n", ret);
		return ret;
	}

	ret = intel_read_evt(ctx->dev, entry.data, sizeof(entry.data));
	if (ret < 0) {
		fprintf(stderr, "failed to read evt(%d)\n", ret);
		return ret;
	}
	entry.len = ret;

	if (entry.data[6] != 0x00) {
		fprintf(stderr, "cmd failed. st=%02x\n", entry.data[6]);
		return -1;
	}

	do {
		ret = intel_read_evt(ctx->dev, entry.data,
					sizeof(entry.data));
		if (ret < 0) {
			fprintf(stderr, "failed to read cmd(%d)\n", ret);
			return ret;
		}
		entry.len = ret;
	} while (!is_startup_evt(entry.data));

	return ret;
}

/**
 * Main routine that handles the device patching process.
 */
static int intel_patch_device(struct patch_ctx *ctx)
{
	int ret;

	ret = pre_patch(ctx);
	if (ret < 0) {
		if (!ctx->patch_error) {
			fprintf(stderr, "I/O error: pre_patch failed\n");
			return ret;
		}

		DBGPRINT("patch failed. proceed to post patch");
		goto post_patch;
	}

	ret = intel_download_patch(ctx);
	if (ret < 0) {
		if (!ctx->patch_error) {
			fprintf(stderr, "I/O error: download_patch failed\n");
			close(ctx->fd);
			return ret;
		}
	} else {
		DBGPRINT("patch done");
		ctx->reset_enable_patch = 1;
	}

	close(ctx->fd);

post_patch:
	ret = post_patch(ctx);
	if (ret < 0) {
		fprintf(stderr, "post_patch failed(%d)\n", ret);
		return ret;
	}

	return 0;
}

static int set_rts(int dev, int rtsval)
{
	int arg;

	if (ioctl(dev, TIOCMGET, &arg) < 0) {
		perror("cannot get TIOCMGET");
		return -errno;
	}
	if (rtsval)
		arg |= TIOCM_RTS;
	else
		arg &= ~TIOCM_RTS;

	if (ioctl(dev, TIOCMSET, &arg) == -1) {
		perror("cannot set TIOCMGET");
		return -errno;
	}

	return 0;
}

static unsigned char get_intel_speed(int speed)
{
	switch (speed) {
	case 9600:
		return 0x00;
	case 19200:
		return 0x01;
	case 38400:
		return 0x02;
	case 57600:
		return 0x03;
	case 115200:
		return 0x04;
	case 230400:
		return 0x05;
	case 460800:
		return 0x06;
	case 921600:
		return 0x07;
	case 1843200:
		return 0x08;
	case 3250000:
		return 0x09;
	case 2000000:
		return 0x0A;
	case 3000000:
		return 0x0B;
	default:
		return 0xFF;
	}
}

/**
 * if it failed to change to new baudrate, it will rollback
 * to initial baudrate
 */
static int change_baudrate(int dev, int init_speed, int *speed,
				struct termios *ti)
{
	int ret;
	unsigned char br;
	unsigned char cmd[5];
	unsigned char evt[7];

	DBGPRINT("start baudrate change");

	ret = set_rts(dev, 0);
	if (ret < 0) {
		fprintf(stderr, "failed to clear RTS\n");
		return ret;
	}

	cmd[0] = HCI_COMMAND_PKT;
	cmd[1] = 0x06;
	cmd[2] = 0xFC;
	cmd[3] = 0x01;

	br = get_intel_speed(*speed);
	if (br == 0xFF) {
		fprintf(stderr, "speed %d is not supported\n", *speed);
		return -1;
	}
	cmd[4] = br;

	ret = intel_write_cmd(dev, cmd, sizeof(cmd));
	if (ret < 0) {
		fprintf(stderr, "failed to send cmd(%d)\n", ret);
		return ret;
	}

	/*
	 *  wait for buffer to be consumed by the controller
	 */
	usleep(300000);

	if (set_speed(dev, ti, *speed) < 0) {
		fprintf(stderr, "can't set to new baud rate\n");
		return -1;
	}

	ret = set_rts(dev, 1);
	if (ret < 0) {
		fprintf(stderr, "failed to set RTS\n");
		return ret;
	}

	ret = intel_read_evt(dev, evt, sizeof(evt));
	if (ret < 0) {
		fprintf(stderr, "failed to read evt(%d)\n", ret);
		return ret;
	}

	if (evt[4] != 0x00) {
		fprintf(stderr,
			"failed to change speed. use default speed %d\n",
			init_speed);
		*speed = init_speed;
	}

	return 0;
}

/**
 * An entry point for Intel specific initialization
 */
int intel_init(int dev, int init_speed, int *speed, struct termios *ti)
{
	int ret = 0;
	struct patch_ctx ctx;

	if (change_baudrate(dev, init_speed, speed, ti) < 0)
		return -1;

	ctx.dev = dev;
	ctx.patch_error = 0;
	ctx.reset_enable_patch = 0;

	ret = intel_patch_device(&ctx);
	if (ret < 0)
		fprintf(stderr, "failed to initialize the device");

	return ret;
}
