/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2000-2001  Qualcomm Incorporated
 *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
 *  Copyright (C) 2002-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 <ctype.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>

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

#include "textfile.h"
#include "csr.h"

static struct hci_dev_info di;
static int all;

static void print_dev_hdr(struct hci_dev_info *di);
static void print_dev_info(int ctl, struct hci_dev_info *di);

static void print_dev_list(int ctl, int flags)
{
	struct hci_dev_list_req *dl;
	struct hci_dev_req *dr;
	int i;

	if (!(dl = malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t)))) {
		perror("Can't allocate memory");
		exit(1);
	}
	dl->dev_num = HCI_MAX_DEV;
	dr = dl->dev_req;

	if (ioctl(ctl, HCIGETDEVLIST, (void *) dl) < 0) {
		perror("Can't get device list");
		exit(1);
	}

	for (i = 0; i< dl->dev_num; i++) {
		di.dev_id = (dr+i)->dev_id;
		if (ioctl(ctl, HCIGETDEVINFO, (void *) &di) < 0)
			continue;
		if (hci_test_bit(HCI_RAW, &di.flags) &&
				!bacmp(&di.bdaddr, BDADDR_ANY)) {
			int dd = hci_open_dev(di.dev_id);
			hci_read_bd_addr(dd, &di.bdaddr, 1000);
			hci_close_dev(dd);
		}
		print_dev_info(ctl, &di);
	}
}

static void print_pkt_type(struct hci_dev_info *di)
{
	printf("\tPacket type: %s\n", hci_ptypetostr(di->pkt_type));
}

static void print_link_policy(struct hci_dev_info *di)
{
	printf("\tLink policy: %s\n", hci_lptostr(di->link_policy));
}

static void print_link_mode(struct hci_dev_info *di)
{
	printf("\tLink mode: %s\n", hci_lmtostr(di->link_mode));
}

static void print_dev_features(struct hci_dev_info *di, int format)
{
	printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
				"0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n",
		di->features[0], di->features[1], di->features[2],
		di->features[3], di->features[4], di->features[5],
		di->features[6], di->features[7]);

	if (format) {
		char *tmp = lmp_featurestostr(di->features, "\t\t", 63);
		printf("%s\n", tmp);
		bt_free(tmp);
	}
}

static void cmd_rstat(int ctl, int hdev, char *opt)
{
	/* Reset HCI device stat counters */
	if (ioctl(ctl, HCIDEVRESTAT, hdev) < 0) {
		fprintf(stderr, "Can't reset stats counters hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}
}

static void cmd_scan(int ctl, int hdev, char *opt)
{
	struct hci_dev_req dr;

	dr.dev_id  = hdev;
	dr.dev_opt = SCAN_DISABLED;
	if (!strcmp(opt, "iscan"))
		dr.dev_opt = SCAN_INQUIRY;
	else if (!strcmp(opt, "pscan"))
		dr.dev_opt = SCAN_PAGE;
	else if (!strcmp(opt, "piscan"))
		dr.dev_opt = SCAN_PAGE | SCAN_INQUIRY;

	if (ioctl(ctl, HCISETSCAN, (unsigned long) &dr) < 0) {
		fprintf(stderr, "Can't set scan mode on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}
}

static void cmd_iac(int ctl, int hdev, char *opt)
{
	int s = hci_open_dev(hdev);

	if (s < 0) {
		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}
	if (opt) {
		int l = strtoul(opt, 0, 16);
		uint8_t lap[3];
		if (!strcasecmp(opt, "giac")) {
			l = 0x9e8b33;
		} else if (!strcasecmp(opt, "liac")) {
			l = 0x9e8b00;
		} else if (l < 0x9e8b00 || l > 0x9e8b3f) {
			printf("Invalid access code 0x%x\n", l);
			exit(1);
		}
		lap[0] = (l & 0xff);
		lap[1] = (l >> 8) & 0xff;
		lap[2] = (l >> 16) & 0xff;
		if (hci_write_current_iac_lap(s, 1, lap, 1000) < 0) {
			printf("Failed to set IAC on hci%d: %s\n", hdev, strerror(errno));
			exit(1);
		}
	} else {
		uint8_t lap[3 * MAX_IAC_LAP];
		int i, j;
		uint8_t n;
		if (hci_read_current_iac_lap(s, &n, lap, 1000) < 0) {
			printf("Failed to read IAC from hci%d: %s\n", hdev, strerror(errno));
			exit(1);
		}
		print_dev_hdr(&di);
		printf("\tIAC: ");
		for (i = 0; i < n; i++) {
			printf("0x");
			for (j = 3; j--; )
				printf("%02x", lap[j + 3 * i]);
			if (i < n - 1)
				printf(", ");
		}
		printf("\n");
	}
	close(s);
}

static void cmd_auth(int ctl, int hdev, char *opt)
{
	struct hci_dev_req dr;

	dr.dev_id = hdev;
	if (!strcmp(opt, "auth"))
		dr.dev_opt = AUTH_ENABLED;
	else
		dr.dev_opt = AUTH_DISABLED;

	if (ioctl(ctl, HCISETAUTH, (unsigned long) &dr) < 0) {
		fprintf(stderr, "Can't set auth on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}
}

static void cmd_encrypt(int ctl, int hdev, char *opt)
{
	struct hci_dev_req dr;

	dr.dev_id = hdev;
	if (!strcmp(opt, "encrypt"))
		dr.dev_opt = ENCRYPT_P2P;
	else
		dr.dev_opt = ENCRYPT_DISABLED;

	if (ioctl(ctl, HCISETENCRYPT, (unsigned long) &dr) < 0) {
		fprintf(stderr, "Can't set encrypt on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}
}

static void cmd_up(int ctl, int hdev, char *opt)
{
	/* Start HCI device */
	if (ioctl(ctl, HCIDEVUP, hdev) < 0) {
		if (errno == EALREADY)
			return;
		fprintf(stderr, "Can't init device hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}
}

static void cmd_down(int ctl, int hdev, char *opt)
{
	/* Stop HCI device */
	if (ioctl(ctl, HCIDEVDOWN, hdev) < 0) {
		fprintf(stderr, "Can't down device hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}
}

static void cmd_reset(int ctl, int hdev, char *opt)
{
	/* Reset HCI device */
#if 0
	if (ioctl(ctl, HCIDEVRESET, hdev) < 0 ){
		fprintf(stderr, "Reset failed for device hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}
#endif
	cmd_down(ctl, hdev, "down");
	cmd_up(ctl, hdev, "up");
}

static void cmd_ptype(int ctl, int hdev, char *opt)
{
	struct hci_dev_req dr;

	dr.dev_id = hdev;

	if (hci_strtoptype(opt, &dr.dev_opt)) {
		if (ioctl(ctl, HCISETPTYPE, (unsigned long) &dr) < 0) {
			fprintf(stderr, "Can't set pkttype on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
			exit(1);
		}
	} else {
		print_dev_hdr(&di);
		print_pkt_type(&di);
	}
}

static void cmd_lp(int ctl, int hdev, char *opt)
{
	struct hci_dev_req dr;

	dr.dev_id = hdev;

	if (hci_strtolp(opt, &dr.dev_opt)) {
		if (ioctl(ctl, HCISETLINKPOL, (unsigned long) &dr) < 0) {
			fprintf(stderr, "Can't set link policy on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
			exit(1);
		}
	} else {
		print_dev_hdr(&di);
		print_link_policy(&di);
	}
}

static void cmd_lm(int ctl, int hdev, char *opt)
{
	struct hci_dev_req dr;

	dr.dev_id = hdev;

	if (hci_strtolm(opt, &dr.dev_opt)) {
		if (ioctl(ctl, HCISETLINKMODE, (unsigned long) &dr) < 0) {
			fprintf(stderr, "Can't set default link mode on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
			exit(1);
		}
	} else {
		print_dev_hdr(&di);
		print_link_mode(&di);
	}
}

static void cmd_aclmtu(int ctl, int hdev, char *opt)
{
	struct hci_dev_req dr = { dev_id: hdev };
	uint16_t mtu, mpkt;

	if (!opt)
		return;

	if (sscanf(opt, "%4hu:%4hu", &mtu, &mpkt) != 2)
		return;

	dr.dev_opt = htobl(htobs(mpkt) | (htobs(mtu) << 16));

	if (ioctl(ctl, HCISETACLMTU, (unsigned long) &dr) < 0) {
		fprintf(stderr, "Can't set ACL mtu on hci%d: %s(%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}
}

static void cmd_scomtu(int ctl, int hdev, char *opt)
{
	struct hci_dev_req dr = { dev_id: hdev };
	uint16_t mtu, mpkt;

	if (!opt)
		return;

	if (sscanf(opt, "%4hu:%4hu", &mtu, &mpkt) != 2)
		return;

	dr.dev_opt = htobl(htobs(mpkt) | (htobs(mtu) << 16));

	if (ioctl(ctl, HCISETSCOMTU, (unsigned long) &dr) < 0) {
		fprintf(stderr, "Can't set SCO mtu on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}
}

static void cmd_features(int ctl, int hdev, char *opt)
{
	uint8_t features[8], max_page = 0;
	char *tmp;
	int i, dd;

	if (!(di.features[7] & LMP_EXT_FEAT)) {
		print_dev_hdr(&di);
		print_dev_features(&di, 1);
		return;
	}

	dd = hci_open_dev(hdev);
	if (dd < 0) {
		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}

	if (hci_read_local_ext_features(dd, 0, &max_page, features, 1000) < 0) {
		fprintf(stderr, "Can't read extended features hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}

	print_dev_hdr(&di);
	printf("\tFeatures%s: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
				"0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n",
		(max_page > 0) ? " page 0" : "",
		features[0], features[1], features[2], features[3],
		features[4], features[5], features[6], features[7]);

	tmp = lmp_featurestostr(di.features, "\t\t", 63);
	printf("%s\n", tmp);
	bt_free(tmp);

	for (i = 1; i <= max_page; i++) {
		if (hci_read_local_ext_features(dd, i, NULL,
							features, 1000) < 0)
			continue;

		printf("\tFeatures page %d: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
					"0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", i,
			features[0], features[1], features[2], features[3],
			features[4], features[5], features[6], features[7]);
	}

	hci_close_dev(dd);
}

static void cmd_name(int ctl, int hdev, char *opt)
{
	int dd;

	dd = hci_open_dev(hdev);
	if (dd < 0) {
		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}

	if (opt) {
		if (hci_write_local_name(dd, opt, 2000) < 0) {
			fprintf(stderr, "Can't change local name on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
			exit(1);
		}
	} else {
		char name[249];
		int i;

		if (hci_read_local_name(dd, sizeof(name), name, 1000) < 0) {
			fprintf(stderr, "Can't read local name on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
			exit(1);
		}

		for (i = 0; i < 248 && name[i]; i++) {
			if ((unsigned char) name[i] < 32 || name[i] == 127)
				name[i] = '.';
		}

		name[248] = '\0';

		print_dev_hdr(&di);
		printf("\tName: '%s'\n", name);
	}

	hci_close_dev(dd);
}

/* 
 * see http://www.bluetooth.org/assigned-numbers/baseband.htm --- all
 * strings are reproduced verbatim
 */
static char *get_minor_device_name(int major, int minor)
{
	switch (major) {
	case 0:	/* misc */
		return "";
	case 1:	/* computer */
		switch(minor) {
		case 0:
			return "Uncategorized";
		case 1:
			return "Desktop workstation";
		case 2:
			return "Server";
		case 3:
			return "Laptop";
		case 4:
			return "Handheld";
		case 5:
			return "Palm";
		case 6:
			return "Wearable";
		}
		break;
	case 2:	/* phone */
		switch(minor) {
		case 0:
			return "Uncategorized";
		case 1:
			return "Cellular";
		case 2:
			return "Cordless";
		case 3:
			return "Smart phone";
		case 4:
			return "Wired modem or voice gateway";
		case 5:
			return "Common ISDN Access";
		case 6:
			return "Sim Card Reader";
		}
		break;
	case 3:	/* lan access */
		if (minor == 0)
			return "Uncategorized";
		switch(minor / 8) {
		case 0:
			return "Fully available";
		case 1:
			return "1-17% utilized";
		case 2:
			return "17-33% utilized";
		case 3:
			return "33-50% utilized";
		case 4:
			return "50-67% utilized";
		case 5:
			return "67-83% utilized";
		case 6:
			return "83-99% utilized";
		case 7:
			return "No service available";
		}
		break;
	case 4:	/* audio/video */
		switch(minor) {
		case 0:
			return "Uncategorized";
		case 1:
			return "Device conforms to the Headset profile";
		case 2:
			return "Hands-free";
			/* 3 is reserved */
		case 4:
			return "Microphone";
		case 5:
			return "Loudspeaker";
		case 6:
			return "Headphones";
		case 7:
			return "Portable Audio";
		case 8:
			return "Car Audio";
		case 9:
			return "Set-top box";
		case 10:
			return "HiFi Audio Device";
		case 11:
			return "VCR";
		case 12:
			return "Video Camera";
		case 13:
			return "Camcorder";
		case 14:
			return "Video Monitor";
		case 15:
			return "Video Display and Loudspeaker";
		case 16:
			return "Video Conferencing";
			/* 17 is reserved */
		case 18:
			return "Gaming/Toy";
		}
		break;
	case 5:	/* peripheral */ {
		static char cls_str[48];
		
		cls_str[0] = '\0';

		switch(minor & 48) {
		case 16:
			strncpy(cls_str, "Keyboard", sizeof(cls_str));
			break;
		case 32:
			strncpy(cls_str, "Pointing device", sizeof(cls_str));
			break;
		case 48:
			strncpy(cls_str, "Combo keyboard/pointing device", sizeof(cls_str));
			break;
		}
		if((minor & 15) && (strlen(cls_str) > 0))
			strcat(cls_str, "/");

		switch(minor & 15) {
		case 0:
			break;
		case 1:
			strncat(cls_str, "Joystick", sizeof(cls_str) - strlen(cls_str));
			break;
		case 2:
			strncat(cls_str, "Gamepad", sizeof(cls_str) - strlen(cls_str));
			break;
		case 3:
			strncat(cls_str, "Remote control", sizeof(cls_str) - strlen(cls_str));
			break;
		case 4:
			strncat(cls_str, "Sensing device", sizeof(cls_str) - strlen(cls_str));
			break;
		case 5:
			strncat(cls_str, "Digitizer tablet", sizeof(cls_str) - strlen(cls_str));
			break;
		case 6:
			strncat(cls_str, "Card reader", sizeof(cls_str) - strlen(cls_str));
			break;
		default:
			strncat(cls_str, "(reserved)", sizeof(cls_str) - strlen(cls_str));
			break;
		}
		if(strlen(cls_str) > 0)
			return cls_str;
	}
	case 6:	/* imaging */
		if (minor & 4)
			return "Display";
		if (minor & 8)
			return "Camera";
		if (minor & 16)
			return "Scanner";
		if (minor & 32)
			return "Printer";
		break;
	case 7: /* wearable */
		switch(minor) {
		case 1:
			return "Wrist Watch";
		case 2:
			return "Pager";
		case 3:
			return "Jacket";
		case 4:
			return "Helmet";
		case 5:
			return "Glasses";
		}
		break;
	case 8: /* toy */
		switch(minor) {
		case 1:
			return "Robot";
		case 2:
			return "Vehicle";
		case 3:
			return "Doll / Action Figure";
		case 4:
			return "Controller";
		case 5:
			return "Game";
		}
		break;
	case 63:	/* uncategorised */
		return "";
	}
	return "Unknown (reserved) minor device class";
}

static void cmd_class(int ctl, int hdev, char *opt)
{
	static const char *services[] = { "Positioning",
					"Networking",
					"Rendering",
					"Capturing",
					"Object Transfer",
					"Audio",
					"Telephony",
					"Information" };
	static const char *major_devices[] = { "Miscellaneous",
					"Computer",
					"Phone",
					"LAN Access",
					"Audio/Video",
					"Peripheral",
					"Imaging",
					"Uncategorized" };
	int s = hci_open_dev(hdev);

	if (s < 0) {
		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}
	if (opt) {
		uint32_t cod = strtoul(opt, NULL, 16);
		if (hci_write_class_of_dev(s, cod, 2000) < 0) {
			fprintf(stderr, "Can't write local class of device on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
			exit(1);
		}
	} else {
		uint8_t cls[3];
		if (hci_read_class_of_dev(s, cls, 1000) < 0) {
			fprintf(stderr, "Can't read class of device on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
			exit(1);
		}
		print_dev_hdr(&di);
		printf("\tClass: 0x%02x%02x%02x\n", cls[2], cls[1], cls[0]);
		printf("\tService Classes: ");
		if (cls[2]) {
			int first = 1;
			for (s = 0; s < (sizeof(services) / sizeof(*services)); s++)
				if (cls[2] & (1 << s)) {
					if (!first)
						printf(", ");
					printf("%s", services[s]);
					first = 0;
				}
		} else
			printf("Unspecified");
		printf("\n\tDevice Class: ");
		if ((cls[1] & 0x1f) >= sizeof(major_devices) / sizeof(*major_devices))
			printf("Invalid Device Class!\n");
		else
			printf("%s, %s\n", major_devices[cls[1] & 0x1f],
				get_minor_device_name(cls[1] & 0x1f, cls[0] >> 2));
	}
}

static void cmd_voice(int ctl, int hdev, char *opt)
{
	static char *icf[] = { "Linear", "u-Law", "A-Law", "Reserved" };
	static char *idf[] = { "1's complement", "2's complement", "Sign-Magnitude", "Reserved" };
	static char *iss[] = { "8 bit", "16 bit" };
	static char *acf[] = { "CVSD", "u-Law", "A-Law", "Reserved" };
	int s = hci_open_dev(hdev);

	if (s < 0) {
		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}
	if (opt) {
		uint16_t vs = htobs(strtoul(opt, NULL, 16));
		if (hci_write_voice_setting(s, vs, 2000) < 0) {
			fprintf(stderr, "Can't write voice setting on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
			exit(1);
		}
	} else {
		uint16_t vs;
		uint8_t ic;
		if (hci_read_voice_setting(s, &vs, 1000) < 0) {
			fprintf(stderr, "Can't read voice setting on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
			exit(1);
		}
		vs = htobs(vs);
		ic = (vs & 0x0300) >> 8;
		print_dev_hdr(&di);
		printf("\tVoice setting: 0x%04x%s\n", vs,
			((vs & 0x03fc) == 0x0060) ? " (Default Condition)" : "");
		printf("\tInput Coding: %s\n", icf[ic]);
		printf("\tInput Data Format: %s\n", idf[(vs & 0xc0) >> 6]);
		if (!ic) {
			printf("\tInput Sample Size: %s\n", iss[(vs & 0x20) >> 5]);
			printf("\t# of bits padding at MSB: %d\n", (vs & 0x1c) >> 2);
		}
		printf("\tAir Coding Format: %s\n", acf[vs & 0x03]);
	}
}

static int get_link_key(const bdaddr_t *local, const bdaddr_t *peer, uint8_t *key)
{
	char filename[PATH_MAX + 1], addr[18], tmp[3], *str;
	int i;

	ba2str(local, addr);
	create_name(filename, PATH_MAX, STORAGEDIR, addr, "linkkeys");

	ba2str(peer, addr);
	str = textfile_get(filename, addr);
	if (!str)
		return -EIO;

	memset(tmp, 0, sizeof(tmp));
	for (i = 0; i < 16; i++) {
		memcpy(tmp, str + (i * 2), 2);
		key[i] = (uint8_t) strtol(tmp, NULL, 16);
	}

	free(str);

	return 0;
}

static void cmd_putkey(int ctl, int hdev, char *opt)
{
	struct hci_dev_info di;
	bdaddr_t bdaddr;
	uint8_t key[16];
	int dd;

	if (!opt)
		return;

	dd = hci_open_dev(hdev);
	if (dd < 0) {
		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}

	if (hci_devinfo(hdev, &di) < 0) {
		fprintf(stderr, "Can't get device info for hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}

	str2ba(opt, &bdaddr);
	if (get_link_key(&di.bdaddr, &bdaddr, key) < 0) {
		fprintf(stderr, "Can't find link key for %s on hci%d\n", opt, hdev);
		exit(1);
	}

	if (hci_write_stored_link_key(dd, &bdaddr, key, 1000) < 0) {
		fprintf(stderr, "Can't write stored link key on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}

	hci_close_dev(dd);
}

static void cmd_delkey(int ctl, int hdev, char *opt)
{
	bdaddr_t bdaddr;
	uint8_t all;
	int dd;

	if (!opt)
		return;

	dd = hci_open_dev(hdev);
	if (dd < 0) {
		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}

	if (!strcasecmp(opt, "all")) {
		bacpy(&bdaddr, BDADDR_ANY);
		all = 1;
	} else {
		str2ba(opt, &bdaddr);
		all = 0;
	}

	if (hci_delete_stored_link_key(dd, &bdaddr, all, 1000) < 0) {
		fprintf(stderr, "Can't delete stored link key on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}

	hci_close_dev(dd);
}

static void cmd_oob_data(int ctl, int hdev, char *opt)
{
	uint8_t hash[16], randomizer[16];
	int i, dd;

	dd = hci_open_dev(hdev);
	if (dd < 0) {
		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}

	if (hci_read_local_oob_data(dd, hash, randomizer, 1000) < 0) {
		fprintf(stderr, "Can't read local OOB data on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}

	print_dev_hdr(&di);
	printf("\tOOB Hash:  ");
	for (i = 0; i < 16; i++)
		printf(" %02x", hash[i]);
	printf("\n\tRandomizer:");
	for (i = 0; i < 16; i++)
		printf(" %02x", randomizer[i]);
	printf("\n");

	hci_close_dev(dd);
}

static void cmd_commands(int ctl, int hdev, char *opt)
{
	uint8_t cmds[64];
	char *str;
	int i, n, dd;

	dd = hci_open_dev(hdev);
	if (dd < 0) {
		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}

	if (hci_read_local_commands(dd, cmds, 1000) < 0) {
		fprintf(stderr, "Can't read support commands on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}

	print_dev_hdr(&di);
	for (i = 0; i < 64; i++) {
		if (!cmds[i])
			continue;

		printf("%s Octet %-2d = 0x%02x (Bit",
			i ? "\t\t ": "\tCommands:", i, cmds[i]);
		for (n = 0; n < 8; n++)
			if (cmds[i] & (1 << n))
				printf(" %d", n);
		printf(")\n");
	}

	str = hci_commandstostr(cmds, "\t", 71);
	printf("%s\n", str);
	bt_free(str);

	hci_close_dev(dd);
}

static void cmd_version(int ctl, int hdev, char *opt)
{
	struct hci_version ver;
	char *hciver, *lmpver;
	int dd;

	dd = hci_open_dev(hdev);
	if (dd < 0) {
		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}

	if (hci_read_local_version(dd, &ver, 1000) < 0) {
		fprintf(stderr, "Can't read version info hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}

	hciver = hci_vertostr(ver.hci_ver);
	lmpver = lmp_vertostr(ver.hci_ver);

	print_dev_hdr(&di);
	printf("\tHCI Ver: %s (0x%x) HCI Rev: 0x%x LMP Ver: %s (0x%x) LMP Subver: 0x%x\n"
		"\tManufacturer: %s (%d)\n",
		hciver ? hciver : "n/a", ver.hci_ver, ver.hci_rev,
		lmpver ? lmpver : "n/a", ver.lmp_ver, ver.lmp_subver,
		bt_compidtostr(ver.manufacturer), ver.manufacturer);

	if (hciver)
		bt_free(hciver);
	if (lmpver)
		bt_free(lmpver);

	hci_close_dev(dd);
}

static void cmd_inq_tpl(int ctl, int hdev, char *opt)
{
	int dd;

	dd = hci_open_dev(hdev);
	if (dd < 0) {
		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}

	if (opt) {
		int8_t level = atoi(opt);

		if (hci_write_inquiry_transmit_power_level(dd, level, 2000) < 0) {
			fprintf(stderr, "Can't set inquiry transmit power level on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
			exit(1);
		}
	} else {
		int8_t level;

		if (hci_read_inquiry_transmit_power_level(dd, &level, 1000) < 0) {
			fprintf(stderr, "Can't read inquiry transmit power level on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
			exit(1);
		}

		print_dev_hdr(&di);
		printf("\tInquiry transmit power level: %d\n", level);
	}

	hci_close_dev(dd);
}

static void cmd_inq_mode(int ctl, int hdev, char *opt)
{
	int dd;

	dd = hci_open_dev(hdev);
	if (dd < 0) {
		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}

	if (opt) {
		uint8_t mode = atoi(opt);

		if (hci_write_inquiry_mode(dd, mode, 2000) < 0) {
			fprintf(stderr, "Can't set inquiry mode on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
			exit(1);
		}
	} else {
		uint8_t mode;

		if (hci_read_inquiry_mode(dd, &mode, 1000) < 0) {
			fprintf(stderr, "Can't read inquiry mode on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
			exit(1);
		}

		print_dev_hdr(&di);
		printf("\tInquiry mode: ");
		switch (mode) {
		case 0:
			printf("Standard Inquiry\n");
			break;
		case 1:
			printf("Inquiry with RSSI\n");
			break;
		case 2:
			printf("Inquiry with RSSI or Extended Inquiry\n");
			break;
		default:
			printf("Unknown (0x%02x)\n", mode);
			break;
		}
	}

	hci_close_dev(dd);
}

static void cmd_inq_data(int ctl, int hdev, char *opt)
{
	int i, dd;

	dd = hci_open_dev(hdev);
	if (dd < 0) {
		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}

	if (opt) {
		uint8_t fec = 0, data[240];
		char tmp[3];
		int i, size;

		memset(data, 0, sizeof(data));

		memset(tmp, 0, sizeof(tmp));
		size = (strlen(opt) + 1) / 2;
		if (size > 240)
			size = 240;

		for (i = 0; i < size; i++) {
			memcpy(tmp, opt + (i * 2), 2);
			data[i] = strtol(tmp, NULL, 16);
		}

		if (hci_write_ext_inquiry_response(dd, fec, data, 2000) < 0) {
			fprintf(stderr, "Can't set extended inquiry response on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
			exit(1);
		}
	} else {
		uint8_t fec, data[240], len, type, *ptr;
		char *str;

		if (hci_read_ext_inquiry_response(dd, &fec, data, 1000) < 0) {
			fprintf(stderr, "Can't read extended inquiry response on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
			exit(1);
		}

		print_dev_hdr(&di);
		printf("\tFEC %s\n\t\t", fec ? "enabled" : "disabled");
		for (i = 0; i < 240; i++)
			printf("%02x%s%s", data[i], (i + 1) % 8 ? "" : " ",
				(i + 1) % 16 ? " " : (i < 239 ? "\n\t\t" : "\n"));

		ptr = data;
		while (*ptr) {
			len = *ptr++;
			type = *ptr++;
			switch (type) {
			case 0x01:
				printf("\tFlags:");
				for (i = 0; i < len - 1; i++)
					printf(" 0x%2.2x", *((uint8_t *) (ptr + i)));
				printf("\n");
				break;
			case 0x02:
			case 0x03:
				printf("\t%s service classes:",
					type == 0x02 ? "Shortened" : "Complete");
				for (i = 0; i < (len - 1) / 2; i++) {
					uint16_t val = btohs(bt_get_unaligned((uint16_t *) (ptr + (i * 2))));
					printf(" 0x%4.4x", val);
				}
				printf("\n");
				break;
			case 0x08:
			case 0x09:
				str = malloc(len);
				if (str) {
					snprintf(str, len, "%s", ptr);
					for (i = 0; i < len - 1; i++) {
						if ((unsigned char) str[i] < 32 || str[i] == 127)
							str[i] = '.';
					}
					printf("\t%s local name: \'%s\'\n",
						type == 0x08 ? "Shortened" : "Complete", str);
					free(str);
				}
				break;
			case 0x0a:
				printf("\tTX power level: %d\n", *((uint8_t *) ptr));
				break;
			default:
				printf("\tUnknown type 0x%02x with %d bytes data\n",
								type, len - 1);
				break;
			}

			ptr += (len - 1);
		}

		printf("\n");
	}

	hci_close_dev(dd);
}

static void cmd_inq_type(int ctl, int hdev, char *opt)
{
	int dd;

	dd = hci_open_dev(hdev);
	if (dd < 0) {
		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}

	if (opt) {
		uint8_t type = atoi(opt);

		if (hci_write_inquiry_scan_type(dd, type, 2000) < 0) {
			fprintf(stderr, "Can't set inquiry scan type on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
			exit(1);
		}
	} else {
		uint8_t type;

		if (hci_read_inquiry_scan_type(dd, &type, 1000) < 0) {
			fprintf(stderr, "Can't read inquiry scan type on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
			exit(1);
		}

		print_dev_hdr(&di);
		printf("\tInquiry scan type: %s\n",
			type == 1 ? "Interlaced Inquiry Scan" : "Standard Inquiry Scan");
	}

	hci_close_dev(dd);
}

static void cmd_inq_parms(int ctl, int hdev, char *opt)
{
	struct hci_request rq;
	int s;

	if ((s = hci_open_dev(hdev)) < 0) {
		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}

	memset(&rq, 0, sizeof(rq));

	if (opt) {
		unsigned int window, interval;
		write_inq_activity_cp cp;

		if (sscanf(opt,"%4u:%4u", &window, &interval) != 2) {
			printf("Invalid argument format\n");
			exit(1);
		}

		rq.ogf = OGF_HOST_CTL;
		rq.ocf = OCF_WRITE_INQ_ACTIVITY;
		rq.cparam = &cp;
		rq.clen = WRITE_INQ_ACTIVITY_CP_SIZE;

		cp.window = htobs((uint16_t) window);
		cp.interval = htobs((uint16_t) interval);

		if (window < 0x12 || window > 0x1000)
			printf("Warning: inquiry window out of range!\n");

		if (interval < 0x12 || interval > 0x1000)
			printf("Warning: inquiry interval out of range!\n");

		if (hci_send_req(s, &rq, 2000) < 0) {
			fprintf(stderr, "Can't set inquiry parameters name on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
			exit(1);
		}
	} else {
		uint16_t window, interval;
		read_inq_activity_rp rp;

		rq.ogf = OGF_HOST_CTL;
		rq.ocf = OCF_READ_INQ_ACTIVITY;
		rq.rparam = &rp;
		rq.rlen = READ_INQ_ACTIVITY_RP_SIZE;

		if (hci_send_req(s, &rq, 1000) < 0) {
			fprintf(stderr, "Can't read inquiry parameters on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
			exit(1);
		}
		if (rp.status) {
			printf("Read inquiry parameters on hci%d returned status %d\n",
							hdev, rp.status);
			exit(1);
		}
		print_dev_hdr(&di);

		window   = btohs(rp.window);
		interval = btohs(rp.interval);
		printf("\tInquiry interval: %u slots (%.2f ms), window: %u slots (%.2f ms)\n",
				interval, (float)interval * 0.625, window, (float)window * 0.625);
	}
}

static void cmd_page_parms(int ctl, int hdev, char *opt)
{
	struct hci_request rq;
	int s;

	if ((s = hci_open_dev(hdev)) < 0) {
		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}

	memset(&rq, 0, sizeof(rq));

	if (opt) {
		unsigned int window, interval;
		write_page_activity_cp cp;

		if (sscanf(opt,"%4u:%4u", &window, &interval) != 2) {
			printf("Invalid argument format\n");
			exit(1);
		}

		rq.ogf = OGF_HOST_CTL;
		rq.ocf = OCF_WRITE_PAGE_ACTIVITY;
		rq.cparam = &cp;
		rq.clen = WRITE_PAGE_ACTIVITY_CP_SIZE;

		cp.window = htobs((uint16_t) window);
		cp.interval = htobs((uint16_t) interval);

		if (window < 0x12 || window > 0x1000)
			printf("Warning: page window out of range!\n");

		if (interval < 0x12 || interval > 0x1000)
			printf("Warning: page interval out of range!\n");

		if (hci_send_req(s, &rq, 2000) < 0) {
			fprintf(stderr, "Can't set page parameters name on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
			exit(1);
		}
	} else {
		uint16_t window, interval;
		read_page_activity_rp rp;

		rq.ogf = OGF_HOST_CTL;
		rq.ocf = OCF_READ_PAGE_ACTIVITY;
		rq.rparam = &rp;
		rq.rlen = READ_PAGE_ACTIVITY_RP_SIZE;

		if (hci_send_req(s, &rq, 1000) < 0) {
			fprintf(stderr, "Can't read page parameters on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
			exit(1);
		}
		if (rp.status) {
			printf("Read page parameters on hci%d returned status %d\n",
							hdev, rp.status);
			exit(1);
		}
		print_dev_hdr(&di);

		window   = btohs(rp.window);
		interval = btohs(rp.interval);
		printf("\tPage interval: %u slots (%.2f ms), window: %u slots (%.2f ms)\n",
				interval, (float)interval * 0.625, window, (float)window * 0.625);
	}
}

static void cmd_page_to(int ctl, int hdev, char *opt)
{
	struct hci_request rq;
	int s;

	if ((s = hci_open_dev(hdev)) < 0) {
		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}

	memset(&rq, 0, sizeof(rq));

	if (opt) {
		unsigned int timeout;
		write_page_timeout_cp cp;

		if (sscanf(opt,"%5u", &timeout) != 1) {
			printf("Invalid argument format\n");
			exit(1);
		}

		rq.ogf = OGF_HOST_CTL;
		rq.ocf = OCF_WRITE_PAGE_TIMEOUT;
		rq.cparam = &cp;
		rq.clen = WRITE_PAGE_TIMEOUT_CP_SIZE;

		cp.timeout = htobs((uint16_t) timeout);

		if (timeout < 0x01 || timeout > 0xFFFF)
			printf("Warning: page timeout out of range!\n");

		if (hci_send_req(s, &rq, 2000) < 0) {
			fprintf(stderr, "Can't set page timeout on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
			exit(1);
		}
	} else {
		uint16_t timeout;
		read_page_timeout_rp rp;

		rq.ogf = OGF_HOST_CTL;
		rq.ocf = OCF_READ_PAGE_TIMEOUT;
		rq.rparam = &rp;
		rq.rlen = READ_PAGE_TIMEOUT_RP_SIZE;

		if (hci_send_req(s, &rq, 1000) < 0) {
			fprintf(stderr, "Can't read page timeout on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
			exit(1);
		}
		if (rp.status) {
			printf("Read page timeout on hci%d returned status %d\n",
							hdev, rp.status);
			exit(1);
		}
		print_dev_hdr(&di);
		
		timeout = btohs(rp.timeout);
		printf("\tPage timeout: %u slots (%.2f ms)\n",
				timeout, (float)timeout * 0.625);
	}
}

static void cmd_afh_mode(int ctl, int hdev, char *opt)
{
	int dd;

	dd = hci_open_dev(hdev);
	if (dd < 0) {
		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}

	if (opt) {
		uint8_t mode = atoi(opt);

		if (hci_write_afh_mode(dd, mode, 2000) < 0) {
			fprintf(stderr, "Can't set AFH mode on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
			exit(1);
		}
	} else {
		uint8_t mode;

		if (hci_read_afh_mode(dd, &mode, 1000) < 0) {
			fprintf(stderr, "Can't read AFH mode on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
			exit(1);
		}

		print_dev_hdr(&di);
		printf("\tAFH mode: %s\n", mode == 1 ? "Enabled" : "Disabled");
	}
}

static void cmd_ssp_mode(int ctl, int hdev, char *opt)
{
	int dd;

	dd = hci_open_dev(hdev);
	if (dd < 0) {
		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}

	if (opt) {
		uint8_t mode = atoi(opt);

		if (hci_write_simple_pairing_mode(dd, mode, 2000) < 0) {
			fprintf(stderr, "Can't set Simple Pairing mode on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
			exit(1);
		}
	} else {
		uint8_t mode;

		if (hci_read_simple_pairing_mode(dd, &mode, 1000) < 0) {
			fprintf(stderr, "Can't read Simple Pairing mode on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
			exit(1);
		}

		print_dev_hdr(&di);
		printf("\tSimple Pairing mode: %s\n", mode == 1 ? "Enabled" : "Disabled");
	}
}

static void print_rev_ericsson(int dd)
{
	struct hci_request rq;
	unsigned char buf[102];

	memset(&rq, 0, sizeof(rq));
	rq.ogf    = OGF_VENDOR_CMD;
	rq.ocf    = 0x000f;
	rq.cparam = NULL;
	rq.clen   = 0;
	rq.rparam = &buf;
	rq.rlen   = sizeof(buf);

	if (hci_send_req(dd, &rq, 1000) < 0) {
		printf("\nCan't read revision info: %s (%d)\n", strerror(errno), errno);
		return;
	}

	printf("\t%s\n", buf + 1);
}

static void print_rev_csr(int dd, uint16_t rev)
{
	uint16_t buildid, chipver, chiprev, maxkeylen, mapsco;

	if (csr_read_varid_uint16(dd, 0, CSR_VARID_BUILDID, &buildid) < 0) {
		printf("\t%s\n", csr_buildidtostr(rev));
		return;
	}

	printf("\t%s\n", csr_buildidtostr(buildid));

	if (!csr_read_varid_uint16(dd, 1, CSR_VARID_CHIPVER, &chipver)) {
		if (csr_read_varid_uint16(dd, 2, CSR_VARID_CHIPREV, &chiprev) < 0)
			chiprev = 0;
		printf("\tChip version: %s\n", csr_chipvertostr(chipver, chiprev));
	}

	if (!csr_read_varid_uint16(dd, 3, CSR_VARID_MAX_CRYPT_KEY_LENGTH, &maxkeylen))
		printf("\tMax key size: %d bit\n", maxkeylen * 8);

	if (!csr_read_pskey_uint16(dd, 4, CSR_PSKEY_HOSTIO_MAP_SCO_PCM, 0x0000, &mapsco))
		printf("\tSCO mapping:  %s\n", mapsco ? "PCM" : "HCI");
}

static void print_rev_digianswer(int dd)
{
	struct hci_request rq;
	unsigned char req[] = { 0x07 };
	unsigned char buf[102];

	memset(&rq, 0, sizeof(rq));
	rq.ogf    = OGF_VENDOR_CMD;
	rq.ocf    = 0x000e;
	rq.cparam = req;
	rq.clen   = sizeof(req);
	rq.rparam = &buf;
	rq.rlen   = sizeof(buf);

	if (hci_send_req(dd, &rq, 1000) < 0) {
		printf("\nCan't read revision info: %s (%d)\n", strerror(errno), errno);
		return;
	}

	printf("\t%s\n", buf + 1);
}

static void print_rev_broadcom(uint16_t hci_rev, uint16_t lmp_subver)
{
	printf("\tFirmware %d.%d / %d\n", hci_rev & 0xff, lmp_subver >> 8, lmp_subver & 0xff);
}

static void print_rev_avm(uint16_t hci_rev, uint16_t lmp_subver)
{
	if (lmp_subver == 0x01)
		printf("\tFirmware 03.%d.%d\n", hci_rev >> 8, hci_rev & 0xff);
	else
		printf("\tUnknown type\n");
}

static void cmd_revision(int ctl, int hdev, char *opt)
{
	struct hci_version ver;
	int dd;

	dd = hci_open_dev(hdev);
	if (dd < 0) {
		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		return;
	}

	if (hci_read_local_version(dd, &ver, 1000) < 0) {
		fprintf(stderr, "Can't read version info for hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		return;
	}

	print_dev_hdr(&di);
	switch (ver.manufacturer) {
	case 0:
	case 37:
	case 48:
		print_rev_ericsson(dd);
		break;
	case 10:
		print_rev_csr(dd, ver.hci_rev);
		break;
	case 12:
		print_rev_digianswer(dd);
		break;
	case 15:
		print_rev_broadcom(ver.hci_rev, ver.lmp_subver);
		break;
	case 31:
		print_rev_avm(ver.hci_rev, ver.lmp_subver);
		break;
	default:
		printf("\tUnsupported manufacturer\n");
		break;
	}
	return;
}

static void print_dev_hdr(struct hci_dev_info *di)
{
	static int hdr = -1;
	char addr[18];

	if (hdr == di->dev_id)
		return;
	hdr = di->dev_id;

	ba2str(&di->bdaddr, addr);

	printf("%s:\tType: %s\n", di->name, hci_dtypetostr(di->type) );
	printf("\tBD Address: %s ACL MTU: %d:%d SCO MTU: %d:%d\n",
		addr, di->acl_mtu, di->acl_pkts,
		di->sco_mtu, di->sco_pkts);
}

static void print_dev_info(int ctl, struct hci_dev_info *di)
{
	struct hci_dev_stats *st = &di->stat;

	print_dev_hdr(di);

	printf("\t%s\n", hci_dflagstostr(di->flags) );

	printf("\tRX bytes:%d acl:%d sco:%d events:%d errors:%d\n",
		st->byte_rx, st->acl_rx, st->sco_rx, st->evt_rx, st->err_rx);

	printf("\tTX bytes:%d acl:%d sco:%d commands:%d errors:%d\n",
		st->byte_tx, st->acl_tx, st->sco_tx, st->cmd_tx, st->err_tx);

	if (all && !hci_test_bit(HCI_RAW, &di->flags) &&
			bacmp(&di->bdaddr, BDADDR_ANY)) {
		print_dev_features(di, 0);
		print_pkt_type(di);
		print_link_policy(di);
		print_link_mode(di);

		if (hci_test_bit(HCI_UP, &di->flags)) {
			cmd_name(ctl, di->dev_id, NULL);
			cmd_class(ctl, di->dev_id, NULL);
			cmd_version(ctl, di->dev_id, NULL);
		}
	}

	printf("\n");
}

static struct {
	char *cmd;
	void (*func)(int ctl, int hdev, char *opt);
	char *opt;
	char *doc;
} command[] = {
	{ "up",		cmd_up,		0,		"Open and initialize HCI device" },
	{ "down",	cmd_down,	0,		"Close HCI device" },
	{ "reset",	cmd_reset,	0,		"Reset HCI device" },
	{ "rstat",	cmd_rstat,	0,		"Reset statistic counters" },
	{ "auth",	cmd_auth,	0,		"Enable Authentication" },
	{ "noauth",	cmd_auth,	0,		"Disable Authentication" },
	{ "encrypt",	cmd_encrypt,	0,		"Enable Encryption" },
	{ "noencrypt",	cmd_encrypt,	0,		"Disable Encryption" },
	{ "piscan",	cmd_scan,	0,		"Enable Page and Inquiry scan" },
	{ "noscan",	cmd_scan,	0,		"Disable scan" },
	{ "iscan",	cmd_scan,	0,		"Enable Inquiry scan" },
	{ "pscan",	cmd_scan,	0,		"Enable Page scan" },
	{ "ptype",	cmd_ptype,	"[type]",	"Get/Set default packet type" },
	{ "lm",		cmd_lm,		"[mode]",	"Get/Set default link mode"   },
	{ "lp",		cmd_lp,		"[policy]",	"Get/Set default link policy" },
	{ "name",	cmd_name,	"[name]",	"Get/Set local name" },
	{ "class",	cmd_class,	"[class]",	"Get/Set class of device" },
	{ "voice",	cmd_voice,	"[voice]",	"Get/Set voice setting" },
	{ "iac",	cmd_iac,	"[iac]",	"Get/Set inquiry access code" },
	{ "inqtpl", 	cmd_inq_tpl,	"[level]",	"Get/Set inquiry transmit power level" },
	{ "inqmode",	cmd_inq_mode,	"[mode]",	"Get/Set inquiry mode" },
	{ "inqdata",	cmd_inq_data,	"[data]",	"Get/Set inquiry data" },
	{ "inqtype",	cmd_inq_type,	"[type]",	"Get/Set inquiry scan type" },
	{ "inqparms",	cmd_inq_parms,	"[win:int]",	"Get/Set inquiry scan window and interval" },
	{ "pageparms",	cmd_page_parms,	"[win:int]",	"Get/Set page scan window and interval" },
	{ "pageto",	cmd_page_to,	"[to]",		"Get/Set page timeout" },
	{ "afhmode",	cmd_afh_mode,	"[mode]",	"Get/Set AFH mode" },
	{ "sspmode",	cmd_ssp_mode,	"[mode]",	"Get/Set Simple Pairing Mode" },
	{ "aclmtu",	cmd_aclmtu,	"<mtu:pkt>",	"Set ACL MTU and number of packets" },
	{ "scomtu",	cmd_scomtu,	"<mtu:pkt>",	"Set SCO MTU and number of packets" },
	{ "putkey",	cmd_putkey,	"<bdaddr>",	"Store link key on the device" },
	{ "delkey",	cmd_delkey,	"<bdaddr>",	"Delete link key from the device" },
	{ "oobdata",	cmd_oob_data,	0,		"Display local OOB data" },
	{ "commands",	cmd_commands,	0,		"Display supported commands" },
	{ "features",	cmd_features,	0,		"Display device features" },
	{ "version",	cmd_version,	0,		"Display version information" },
	{ "revision",	cmd_revision,	0,		"Display revision information" },
	{ NULL, NULL, 0 }
};

static void usage(void)
{
	int i;

	printf("hciconfig - HCI device configuration utility\n");
	printf("Usage:\n"
		"\thciconfig\n"
		"\thciconfig [-a] hciX [command]\n");
	printf("Commands:\n");
	for (i=0; command[i].cmd; i++)
		printf("\t%-10s %-8s\t%s\n", command[i].cmd,
		command[i].opt ? command[i].opt : " ",
		command[i].doc);
}

static struct option main_options[] = {
	{ "help",	0, 0, 'h' },
	{ "all",	0, 0, 'a' },
	{ 0, 0, 0, 0 }
};

int main(int argc, char *argv[])
{
	int opt, ctl, i, cmd=0;

	while ((opt=getopt_long(argc, argv, "ah", main_options, NULL)) != -1) {
		switch(opt) {
		case 'a':
			all = 1;
			break;

		case 'h':
		default:
			usage();
			exit(0);
		}
	}

	argc -= optind;
	argv += optind;
	optind = 0;

	/* Open HCI socket  */
	if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) {
		perror("Can't open HCI socket.");
		exit(1);
	}

	if (argc < 1) {
		print_dev_list(ctl, 0);
		exit(0);
	}

	di.dev_id = atoi(argv[0] + 3);
	argc--; argv++;

	if (ioctl(ctl, HCIGETDEVINFO, (void *) &di)) {
		perror("Can't get device info");
		exit(1);
	}

	if (hci_test_bit(HCI_RAW, &di.flags) &&
			!bacmp(&di.bdaddr, BDADDR_ANY)) {
		int dd = hci_open_dev(di.dev_id);
		hci_read_bd_addr(dd, &di.bdaddr, 1000);
		hci_close_dev(dd);
	}

	while (argc > 0) {
		for (i = 0; command[i].cmd; i++) {
			if (strncmp(command[i].cmd, *argv, 5))
				continue;

			if (command[i].opt) {
				argc--; argv++;
			}

			command[i].func(ctl, di.dev_id, *argv);
			cmd = 1;
			break;
		}
		argc--; argv++;
	}

	if (!cmd)
		print_dev_info(ctl, &di);

	close(ctl);
	return 0;
}
