/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2000-2001  Qualcomm Incorporated
 *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
 *  Copyright (C) 2002-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 <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)
{
	char *str;
	str = hci_ptypetostr(di->pkt_type);
	printf("\tPacket type: %s\n", str);
	bt_free(str);
}

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)
{
	char *str;
	str =  hci_lmtostr(di->link_mode);
	printf("\tLink mode: %s\n", str);
	bt_free(str);
}

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 print_le_states(uint64_t states)
{
	int i;
	const char *le_states[] = {
		"Non-connectable Advertising State" ,
		"Scannable Advertising State",
		"Connectable Advertising State",
		"Directed Advertising State",
		"Passive Scanning State",
		"Active Scanning State",
		"Initiating State/Connection State in Master Role",
		"Connection State in the Slave Role",
		"Non-connectable Advertising State and Passive Scanning State combination",
		"Scannable Advertising State and Passive Scanning State combination",
		"Connectable Advertising State and Passive Scanning State combination",
		"Directed Advertising State and Passive Scanning State combination",
		"Non-connectable Advertising State and Active Scanning State combination",
		"Scannable Advertising State and Active Scanning State combination",
		"Connectable Advertising State and Active Scanning State combination",
		"Directed Advertising State and Active Scanning State combination",
		"Non-connectable Advertising State and Initiating State combination",
		"Scannable Advertising State and Initiating State combination",
		"Non-connectable Advertising State and Master Role combination",
		"Scannable Advertising State and Master Role combination",
		"Non-connectable Advertising State and Slave Role combination",
		"Scannable Advertising State and Slave Role combination",
		"Passive Scanning State and Initiating State combination",
		"Active Scanning State and Initiating State combination",
		"Passive Scanning State and Master Role combination",
		"Active Scanning State and Master Role combination",
		"Passive Scanning State and Slave Role combination",
		"Active Scanning State and Slave Role combination",
		"Initiating State and Master Role combination/Master Role and Master Role combination",
		NULL
	};

	printf("Supported link layer states:\n");
	for (i = 0; le_states[i]; i++) {
		const char *status;

		status = states & (1 << i) ? "YES" : "NO ";
		printf("\t%s %s\n", status, le_states[i]);
	}
}

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_le_addr(int ctl, int hdev, char *opt)
{
	struct hci_request rq;
	le_set_random_address_cp cp;
	uint8_t status;
	int dd, err, ret;

	if (!opt)
		return;

	if (hdev < 0)
		hdev = hci_get_route(NULL);

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

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

	str2ba(opt, &cp.bdaddr);

	memset(&rq, 0, sizeof(rq));
	rq.ogf = OGF_LE_CTL;
	rq.ocf = OCF_LE_SET_RANDOM_ADDRESS;
	rq.cparam = &cp;
	rq.clen = LE_SET_RANDOM_ADDRESS_CP_SIZE;
	rq.rparam = &status;
	rq.rlen = 1;

	ret = hci_send_req(dd, &rq, 1000);
	if (status || ret < 0) {
		err = errno;
		fprintf(stderr, "Can't set random address for hci%d: "
					"%s (%d)\n", hdev, strerror(err), err);
	}

	hci_close_dev(dd);
}

static void cmd_le_adv(int ctl, int hdev, char *opt)
{
	struct hci_request rq;
	le_set_advertise_enable_cp advertise_cp;
	uint8_t status;
	int dd, ret;

	if (hdev < 0)
		hdev = hci_get_route(NULL);

	dd = hci_open_dev(hdev);
	if (dd < 0) {
		perror("Could not open device");
		exit(1);
	}

	memset(&advertise_cp, 0, sizeof(advertise_cp));
	if (strcmp(opt, "noleadv") == 0)
		advertise_cp.enable = 0x00;
	else
		advertise_cp.enable = 0x01;

	memset(&rq, 0, sizeof(rq));
	rq.ogf = OGF_LE_CTL;
	rq.ocf = OCF_LE_SET_ADVERTISE_ENABLE;
	rq.cparam = &advertise_cp;
	rq.clen = LE_SET_ADVERTISE_ENABLE_CP_SIZE;
	rq.rparam = &status;
	rq.rlen = 1;

	ret = hci_send_req(dd, &rq, 1000);

	hci_close_dev(dd);

	if (ret < 0) {
		fprintf(stderr, "Can't set advertise mode on hci%d: %s (%d)\n",
						hdev, strerror(errno), errno);
		exit(1);
	}

	if (status) {
		fprintf(stderr, "LE set advertise enable on hci%d returned status %d\n",
						hdev, status);
		exit(1);
	}
}

static void cmd_le_states(int ctl, int hdev, char *opt)
{
	le_read_supported_states_rp rp;
	struct hci_request rq;
	int err, dd;

	if (hdev < 0)
		hdev = hci_get_route(NULL);

	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);
	}

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

	rq.ogf    = OGF_LE_CTL;
	rq.ocf    = OCF_LE_READ_SUPPORTED_STATES;
	rq.rparam = &rp;
	rq.rlen   = LE_READ_SUPPORTED_STATES_RP_SIZE;

	err = hci_send_req(dd, &rq, 1000);

	hci_close_dev(dd);

	if (err < 0) {
		fprintf(stderr, "Can't read LE supported states on hci%d:"
				" %s(%d)\n", hdev, strerror(errno), errno);
		exit(1);
	}

	if (rp.status) {
		fprintf(stderr, "Read LE supported states on hci%d"
				" returned status %d\n", hdev, rp.status);
		exit(1);
	}

	print_le_states(rp.states);
}

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]) {
			unsigned int i;
			int first = 1;
			for (i = 0; i < (sizeof(services) / sizeof(*services)); i++)
				if (cls[2] & (1 << i)) {
					if (!first)
						printf(", ");
					printf("%s", services[i]);
					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.lmp_ver);

	print_dev_hdr(&di);
	printf("\tHCI Version: %s (0x%x)  Revision: 0x%x\n"
		"\tLMP Version: %s (0x%x)  Subversion: 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_inq_response_tx_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[HCI_MAX_EIR_LENGTH];
		char tmp[3];
		int i, size;

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

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

		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[HCI_MAX_EIR_LENGTH], 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 < HCI_MAX_EIR_LENGTH; 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", *((int8_t *) ptr));
				break;
			case 0x10:
				printf("\tDevice ID with %d bytes data\n",
								len - 1);
				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 cmd_block(int ctl, int hdev, char *opt)
{
	bdaddr_t bdaddr;
	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);
	}

	str2ba(opt, &bdaddr);

	if (ioctl(dd, HCIBLOCKADDR, &bdaddr) < 0) {
		perror("ioctl(HCIBLOCKADDR)");
		exit(1);
	}

	hci_close_dev(dd);
}

static void cmd_unblock(int ctl, int hdev, char *opt)
{
	bdaddr_t bdaddr;
	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);
	else
		str2ba(opt, &bdaddr);

	if (ioctl(dd, HCIUNBLOCKADDR, &bdaddr) < 0) {
		perror("ioctl(HCIUNBLOCKADDR)");
		exit(1);
	}

	hci_close_dev(dd);
}

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  Bus: %s\n", di->name,
					hci_typetostr(di->type >> 4),
					hci_bustostr(di->type & 0x0f));
	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;
	char *str;

	print_dev_hdr(di);

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

	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" },
	{ "block",	cmd_block,	"<bdaddr>",	"Add a device to the blacklist" },
	{ "unblock",	cmd_unblock,	"<bdaddr>",	"Remove a device from the blacklist" },
	{ "lerandaddr", cmd_le_addr,	"<bdaddr>",	"Set LE Random Address" },
	{ "leadv",	cmd_le_adv,	0,		"Enable LE advertising" },
	{ "noleadv",	cmd_le_adv,	0,		"Disable LE advertising" },
	{ "lestates",	cmd_le_states,	0,		"Display the supported LE states" },
	{ 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, strlen(command[i].cmd)))
				continue;

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

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

		if (command[i].cmd == 0)
			fprintf(stderr, "Warning: unknown command - \"%s\"\n",
					*argv);

		argc--; argv++;
	}

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

	close(ctl);
	return 0;
}
