/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2007-2008  Texas Instruments, Inc.
 *  Copyright (C) 2005-2008  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 <termios.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/uio.h>

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

#ifdef HCIATTACH_DEBUG
#define DPRINTF(x...)	printf(x)
#else
#define DPRINTF(x...)
#endif

#define HCIUARTGETDEVICE	_IOR('U', 202, int)

#define MAKEWORD(a, b)  ((uint16_t)(((uint8_t)(a)) | ((uint16_t)((uint8_t)(b))) << 8))

#define TI_MANUFACTURER_ID	13

#define FIRMWARE_DIRECTORY	"/lib/firmware/"

#define ACTION_SEND_COMMAND	1
#define ACTION_WAIT_EVENT	2
#define ACTION_SERIAL		3
#define ACTION_DELAY		4
#define ACTION_RUN_SCRIPT	5
#define ACTION_REMARKS		6

#define BRF_DEEP_SLEEP_OPCODE_BYTE_1	0x0c
#define BRF_DEEP_SLEEP_OPCODE_BYTE_2	0xfd
#define BRF_DEEP_SLEEP_OPCODE		\
	(BRF_DEEP_SLEEP_OPCODE_BYTE_1 | (BRF_DEEP_SLEEP_OPCODE_BYTE_2 << 8))

#define FILE_HEADER_MAGIC	0x42535442

/*
 * BRF Firmware header
 */
struct bts_header {
	uint32_t	magic;
	uint32_t	version;
	uint8_t	future[24];
	uint8_t	actions[0];
}__attribute__ ((packed));

/*
 * BRF Actions structure
 */
struct bts_action {
	uint16_t	type;
	uint16_t	size;
	uint8_t	data[0];
} __attribute__ ((packed));

struct bts_action_send {
	uint8_t data[0];
} __attribute__ ((packed));

struct bts_action_wait {
	uint32_t msec;
	uint32_t size;
	uint8_t data[0];
}__attribute__ ((packed));

struct bts_action_delay {
	uint32_t msec;
}__attribute__ ((packed));

struct bts_action_serial {
	uint32_t baud;
	uint32_t flow_control;
}__attribute__ ((packed));

extern int set_speed(int fd, struct termios *ti, int speed);
extern int read_hci_event(int fd, unsigned char* buf, int size);

static FILE *bts_load_script(const char* file_name, uint32_t* version)
{
	struct bts_header header;
	FILE* fp;

	fp = fopen(file_name, "rb");
	if (!fp) {
		perror("can't open firmware file");
		goto out;
	}

	if (1 != fread(&header, sizeof(struct bts_header), 1, fp)) {
		perror("can't read firmware file");
		goto errclose;
	}

	if (header.magic != FILE_HEADER_MAGIC) {
		fprintf(stderr, "%s not a legal TI firmware file\n", file_name);
		goto errclose;
	}

	if (NULL != version)
		*version = header.version;

	goto out;

errclose:
	fclose(fp);
	fp = NULL;
out:
	return fp;
}

static unsigned long bts_fetch_action(FILE* fp, unsigned char* action_buf,
				unsigned long buf_size, uint16_t* action_type)
{
	struct bts_action action_hdr;
	unsigned long nread;

	if (!fp)
		return 0;

	if (1 != fread(&action_hdr, sizeof(struct bts_action), 1, fp))
		return 0;

	if (action_hdr.size > buf_size) {
		fprintf(stderr, "bts_next_action: not enough space to read next action\n");
		return 0;
	}

	nread = fread(action_buf, sizeof(uint8_t), action_hdr.size, fp);
	if (nread != (action_hdr.size)) {
		fprintf(stderr, "bts_next_action: fread failed to read next action\n");
		return 0;
	}

	*action_type = action_hdr.type;

	return nread * sizeof(uint8_t);
}

static void bts_unload_script(FILE* fp)
{
	if (fp)
		fclose(fp);
}

static int is_it_texas(const uint8_t *respond)
{
	uint16_t manufacturer_id;

	manufacturer_id = MAKEWORD(respond[11], respond[12]);

	return TI_MANUFACTURER_ID == manufacturer_id ? 1 : 0;
}

static const char *get_firmware_name(const uint8_t *respond)
{
	static char firmware_file_name[PATH_MAX] = {0};
	uint16_t version = 0, chip = 0, min_ver = 0, maj_ver = 0;

	version = MAKEWORD(respond[13], respond[14]);
	chip =  (version & 0x7C00) >> 10;
	min_ver = (version & 0x007F);
	maj_ver = (version & 0x0380) >> 7;

	if (version & 0x8000)
		maj_ver |= 0x0008;

	sprintf(firmware_file_name, FIRMWARE_DIRECTORY "TIInit_%d.%d.%d.bts", chip, maj_ver, min_ver);

	return firmware_file_name;
}

static void brf_delay(struct bts_action_delay *delay)
{
	usleep(1000 * delay->msec);
}

static int brf_set_serial_params(struct bts_action_serial *serial_action,
						int fd, struct termios *ti)
{
	fprintf(stderr, "texas: changing baud rate to %u, flow control to %u\n",
				serial_action->baud, serial_action->flow_control );
	tcflush(fd, TCIOFLUSH);

	if (serial_action->flow_control)
		ti->c_cflag |= CRTSCTS;
	else
		ti->c_cflag &= ~CRTSCTS;

	if (tcsetattr(fd, TCSANOW, ti) < 0) {
		perror("Can't set port settings");
		return -1;
	}

	tcflush(fd, TCIOFLUSH);

	if (set_speed(fd, ti, serial_action->baud) < 0) {
		perror("Can't set baud rate");
		return -1;
	}

	return 0;
}

static int brf_send_command_socket(int fd, struct bts_action_send* send_action)
{
	char response[1024] = {0};
	hci_command_hdr *cmd = (hci_command_hdr *) send_action->data;
	uint16_t opcode = cmd->opcode;

	struct hci_request rq;
	memset(&rq, 0, sizeof(rq));
	rq.ogf    = cmd_opcode_ogf(opcode);
	rq.ocf    = cmd_opcode_ocf(opcode);
	rq.event  = EVT_CMD_COMPLETE;
	rq.cparam = &send_action->data[3];
	rq.clen   = send_action->data[2];
	rq.rparam = response;
	rq.rlen   = sizeof(response);

	if (hci_send_req(fd, &rq, 15) < 0) {
		perror("Cannot send hci command to socket");
		return -1;
	}

	/* verify success */
	if (response[0]) {
		errno = EIO;
		return -1;
	}

	return 0;
}

static int brf_send_command_file(int fd, struct bts_action_send* send_action, long size)
{
	unsigned char response[1024] = {0};
	long ret = 0;

	/* send command */
	if (size != write(fd, send_action, size)) {
		perror("Texas: Failed to write action command");
		return -1;
	}

	/* read response */
	ret = read_hci_event(fd, response, sizeof(response));
	if (ret < 0) {
		perror("texas: failed to read command response");
		return -1;
	}

	/* verify success */
	if (ret < 7 || 0 != response[6]) {
		fprintf( stderr, "TI init command failed.\n" );
		errno = EIO;
		return -1;
	}

	return 0;
}


static int brf_send_command(int fd, struct bts_action_send* send_action, long size, int hcill_installed)
{
	int ret = 0;
	char *fixed_action;

	/* remove packet type when giving to socket API */
	if (hcill_installed) {
		fixed_action = ((char *) send_action) + 1;
		ret = brf_send_command_socket(fd, (struct bts_action_send *) fixed_action);
	} else {
		ret = brf_send_command_file(fd, send_action, size);
	}

	return ret;
}

static int brf_do_action(uint16_t brf_type, uint8_t *brf_action, long brf_size,
				int fd, struct termios *ti, int hcill_installed)
{
	int ret = 0;

	switch (brf_type) {
	case ACTION_SEND_COMMAND:
		DPRINTF("W");
		ret = brf_send_command(fd, (struct bts_action_send*) brf_action, brf_size, hcill_installed);
		break;
	case ACTION_WAIT_EVENT:
		DPRINTF("R");
		break;
	case ACTION_SERIAL:
		DPRINTF("S");
		ret = brf_set_serial_params((struct bts_action_serial *) brf_action, fd, ti);
		break;
	case ACTION_DELAY:
		DPRINTF("D");
		brf_delay((struct bts_action_delay *) brf_action);
		break;
	case ACTION_REMARKS:
		DPRINTF("C");
		break;
	default:
		fprintf(stderr, "brf_init: unknown firmware action type (%d)\n", brf_type);
		break;
	}

	return ret;
}

/*
 * tests whether a given brf action is a HCI_VS_Sleep_Mode_Configurations cmd
 */
static int brf_action_is_deep_sleep(uint8_t *brf_action, long brf_size,
							uint16_t brf_type)
{
	uint16_t opcode;

	if (brf_type != ACTION_SEND_COMMAND)
		return 0;

	if (brf_size < 3)
		return 0;

	if (brf_action[0] != HCI_COMMAND_PKT)
		return 0;

	/* HCI data is little endian */
	opcode = brf_action[1] | (brf_action[2] << 8);

	if (opcode != BRF_DEEP_SLEEP_OPCODE)
		return 0;

	/* action is deep sleep configuration command ! */
	return 1;
}

/*
 * This function is called twice.
 * The first time it is called, it loads the brf script, and executes its
 * commands until it reaches a deep sleep command (or its end).
 * The second time it is called, it assumes HCILL protocol is set up,
 * and sends rest of brf script via the supplied socket.
 */
static int brf_do_script(int fd, struct termios *ti, const char *bts_file)
{
	int ret = 0,  hcill_installed = bts_file ? 0 : 1;
	uint32_t vers;
	static FILE *brf_script_file = NULL;
	static uint8_t brf_action[256];
	static long brf_size;
	static uint16_t brf_type;

	/* is it the first time we are called ? */
	if (0 == hcill_installed) {
		DPRINTF("Sending script to serial device\n");
		brf_script_file = bts_load_script(bts_file, &vers );
		if (!brf_script_file) {
			fprintf(stderr, "Warning: cannot find BTS file: %s\n",
					bts_file);
			return 0;
		}

		fprintf( stderr, "Loaded BTS script version %u\n", vers );

		brf_size = bts_fetch_action(brf_script_file, brf_action,
						sizeof(brf_action), &brf_type);
		if (brf_size == 0) {
			fprintf(stderr, "Warning: BTS file is empty !");
			return 0;
		}
	}
	else {
		DPRINTF("Sending script to bluetooth socket\n");
	}

	/* execute current action and continue to parse brf script file */
	while (brf_size != 0) {
		ret = brf_do_action(brf_type, brf_action, brf_size,
						fd, ti, hcill_installed);
		if (ret == -1)
			break;

		brf_size = bts_fetch_action(brf_script_file, brf_action,
						sizeof(brf_action), &brf_type);

		/* if this is the first time we run (no HCILL yet) */
		/* and a deep sleep command is encountered */
		/* we exit */
		if (!hcill_installed &&
				brf_action_is_deep_sleep(brf_action,
							brf_size, brf_type))
			return 0;
	}

	bts_unload_script(brf_script_file);
	brf_script_file = NULL;
	DPRINTF("\n");

	return ret;
}

int texas_init(int fd, struct termios *ti)
{
	struct timespec tm = {0, 50000};
	char cmd[4];
	unsigned char resp[100];		/* Response */
	const char *bts_file;
	int n;

	memset(resp,'\0', 100);

	/* It is possible to get software version with manufacturer specific 
	   HCI command HCI_VS_TI_Version_Number. But the only thing you get more
	   is if this is point-to-point or point-to-multipoint module */

	/* Get Manufacturer and LMP version */
	cmd[0] = HCI_COMMAND_PKT;
	cmd[1] = 0x01;
	cmd[2] = 0x10;
	cmd[3] = 0x00;

	do {
		n = write(fd, cmd, 4);
		if (n < 0) {
			perror("Failed to write init command (READ_LOCAL_VERSION_INFORMATION)");
			return -1;
		}
		if (n < 4) {
			fprintf(stderr, "Wanted to write 4 bytes, could only write %d. Stop\n", n);
			return -1;
		}

		/* Read reply. */
		if (read_hci_event(fd, resp, 100) < 0) {
			perror("Failed to read init response (READ_LOCAL_VERSION_INFORMATION)");
			return -1;
		}

		/* Wait for command complete event for our Opcode */
	} while (resp[4] != cmd[1] && resp[5] != cmd[2]);

	/* Verify manufacturer */
	if (! is_it_texas(resp)) {
		fprintf(stderr,"ERROR: module's manufacturer is not Texas Instruments\n");
		return -1;
	}

	fprintf(stderr, "Found a Texas Instruments' chip!\n");

	bts_file = get_firmware_name(resp);
	fprintf(stderr, "Firmware file : %s\n", bts_file);

	n = brf_do_script(fd, ti, bts_file);

	nanosleep(&tm, NULL);

	return n;
}

int texas_post(int fd, struct termios *ti)
{
	int dev_id, dd, ret = 0;

	sleep(1);

	dev_id = ioctl(fd, HCIUARTGETDEVICE, 0);
	if (dev_id < 0) {
		perror("cannot get device id");
		return -1;
	}

	DPRINTF("\nAdded device hci%d\n", dev_id);

	dd = hci_open_dev(dev_id);
	if (dd < 0) {
		perror("HCI device open failed");
		return -1;
	}

	ret = brf_do_script(dd, ti, NULL);

	hci_close_dev(dd);

	return ret;
}
