/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2005-2010  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 <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <dirent.h>
#include <sys/param.h>

#include "lib/bluetooth.h"

#include "hciattach.h"

static int debug = 0;

static int do_command(int fd, uint8_t ogf, uint16_t ocf,
			uint8_t *cparam, int clen, uint8_t *rparam, int rlen)
{
	//uint16_t opcode = (uint16_t) ((ocf & 0x03ff) | (ogf << 10));
	unsigned char cp[260], rp[260];
	int len, size, offset = 3;

	cp[0] = 0x01;
	cp[1] = ocf & 0xff;
	cp[2] = ogf << 2 | ocf >> 8;
	cp[3] = clen;

	if (clen > 0)
		memcpy(cp + 4, cparam, clen);

	if (debug) {
		int i;
		printf("[<");
		for (i = 0; i < clen + 4; i++)
			printf(" %02x", cp[i]);
		printf("]\n");
	}

	if (write(fd, cp, clen + 4) < 0)
		return -1;

	do {
		if (read(fd, rp, 1) < 1)
			return -1;
	} while (rp[0] != 0x04);

	if (read(fd, rp + 1, 2) < 2)
		return -1;

	do {
		len = read(fd, rp + offset, sizeof(rp) - offset);
		offset += len;
	} while (offset < rp[2] + 3);

	if (debug) {
		int i;
		printf("[>");
		for (i = 0; i < offset; i++)
			printf(" %02x", rp[i]);
		printf("]\n");
	}

	if (rp[0] != 0x04) {
		errno = EIO;
		return -1;
	}

	switch (rp[1]) {
	case 0x0e:	/* command complete */
		if (rp[6] != 0x00)
			return -ENXIO;
		offset = 3 + 4;
		size = rp[2] - 4;
		break;
	case 0x0f:	/* command status */
		/* fall through */
	default:
		offset = 3;
		size = rp[2];
		break;
	}

	if (!rparam || rlen < size)
		return -ENXIO;

	memcpy(rparam, rp + offset, size);

	return size;
}

static int load_file(int dd, uint16_t version, const char *suffix)
{
	DIR *dir;
	struct dirent *d;
	char pathname[PATH_MAX], filename[NAME_MAX], prefix[20];
	unsigned char cmd[256];
	unsigned char buf[256];
	uint8_t seqnum = 0;
	int fd, size, len, found_fw_file;

	memset(filename, 0, sizeof(filename));

	snprintf(prefix, sizeof(prefix), "STLC2500_R%d_%02d_",
						version >> 8, version & 0xff);

	strcpy(pathname, "/lib/firmware");
	dir = opendir(pathname);
	if (!dir) {
		strcpy(pathname, ".");
		dir = opendir(pathname);
		if (!dir)
			return -errno;
	}

	found_fw_file = 0;
	while (1) {
		d = readdir(dir);
		if (!d)
			break;

		if (strncmp(d->d_name + strlen(d->d_name) - strlen(suffix),
						suffix, strlen(suffix)))
			continue;

		if (strncmp(d->d_name, prefix, strlen(prefix)))
			continue;

		snprintf(filename, sizeof(filename), "%s/%s",
							pathname, d->d_name);
		found_fw_file = 1;
	}

	closedir(dir);

	if (!found_fw_file)
		return -ENOENT;

	printf("Loading file %s\n", filename);

	fd = open(filename, O_RDONLY);
	if (fd < 0) {
		perror("Can't open firmware file");
		return -errno;
	}

	while (1) {
		size = read(fd, cmd + 1, 254);
		if (size <= 0)
			break;

		cmd[0] = seqnum;

		len = do_command(dd, 0xff, 0x002e, cmd, size + 1, buf, sizeof(buf));
		if (len < 1)
			break;

		if (buf[0] != seqnum) {
			fprintf(stderr, "Sequence number mismatch\n");
			break;
		}

		seqnum++;
	}

	close(fd);

	return 0;
}

int stlc2500_init(int dd, bdaddr_t *bdaddr)
{
	unsigned char cmd[16];
	unsigned char buf[254];
	uint16_t version;
	int len;
	int err;

	/* Hci_Cmd_Ericsson_Read_Revision_Information */
	len = do_command(dd, 0xff, 0x000f, NULL, 0, buf, sizeof(buf));
	if (len < 0)
		return -1;

	printf("%s\n", buf);

	/* HCI_Read_Local_Version_Information */
	len = do_command(dd, 0x04, 0x0001, NULL, 0, buf, sizeof(buf));
	if (len < 0)
		return -1;

	version = buf[2] << 8 | buf[1];

	err = load_file(dd, version, ".ptc");
	if (err < 0) {
		if (err == -ENOENT)
			fprintf(stderr, "No ROM patch file loaded.\n");
		else
			return -1;
	}

	err = load_file(dd, buf[2] << 8 | buf[1], ".ssf");
	if (err < 0) {
		if (err == -ENOENT)
			fprintf(stderr, "No static settings file loaded.\n");
		else
			return -1;
	}

	cmd[0] = 0xfe;
	cmd[1] = 0x06;
	bacpy((bdaddr_t *) (cmd + 2), bdaddr);

	/* Hci_Cmd_ST_Store_In_NVDS */
	len = do_command(dd, 0xff, 0x0022, cmd, 8, buf, sizeof(buf));
	if (len < 0)
		return -1;

	/* HCI_Reset : applies parameters*/
	len = do_command(dd, 0x03, 0x0003, NULL, 0, buf, sizeof(buf));
	if (len < 0)
		return -1;

	return 0;
}

int bgb2xx_init(int dd, bdaddr_t *bdaddr)
{
	unsigned char cmd[16];
	unsigned char buf[254];
	int len;

	len = do_command(dd, 0xff, 0x000f, NULL, 0, buf, sizeof(buf));
	if (len < 0)
		return -1;

	printf("%s\n", buf);

	cmd[0] = 0xfe;
	cmd[1] = 0x06;
	bacpy((bdaddr_t *) (cmd + 2), bdaddr);

	len = do_command(dd, 0xff, 0x0022, cmd, 8, buf, sizeof(buf));
	if (len < 0)
		return -1;

	len = do_command(dd, 0x03, 0x0003, NULL, 0, buf, sizeof(buf));
	if (len < 0)
		return -1;

	return 0;
}
