/*
 *
 *  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_secmgr(int ctl, int hdev, char *opt)
{
	int val, s = hci_open_dev(hdev);

	if (!strcmp(opt, "secmgr"))
		val = 1;
	else
		val = 0;

	if (ioctl(s, HCISETSECMGR, val) < 0) {
		fprintf(stderr, "Can't set security manager on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}
	close(s);
}

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 max_page, features[8];
	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);
	tmp = lmp_featurestostr(di.features, "\t\t", 63);
	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]);
	printf("%s\n", tmp);
	bt_free(tmp);

	for (i = 1; i <= max_page; i++) {
		if (hci_read_local_ext_features(dd, 1, &max_page, 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 char *services[] = { "Positioning",
					"Networking",
					"Rendering",
					"Capturing",
					"Object Transfer",
					"Audio",
					"Telephony",
					"Information" };
	static 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(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" },
	{ "secmgr",	cmd_secmgr,	0,		"Enable Security Manager" },
	{ "nosecmgr",	cmd_secmgr,	0,		"Disable Security Manager" },
	{ "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;
}
