/*
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2011  Intel Corporation. All rights reserved.
 *
 *  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 <stdarg.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <poll.h>
#include <getopt.h>
#include <stdbool.h>
#include <wordexp.h>
#include <ctype.h>

#include "lib/bluetooth.h"
#include "lib/hci.h"
#include "lib/hci_lib.h"
#include "lib/sdp.h"
#include "lib/sdp_lib.h"

#include "src/uuid-helper.h"
#include "lib/mgmt.h"

#include "src/shared/mainloop.h"
#include "src/shared/io.h"
#include "src/shared/util.h"
#include "src/shared/mgmt.h"
#include "src/shared/shell.h"

#define SCAN_TYPE_BREDR (1 << BDADDR_BREDR)
#define SCAN_TYPE_LE ((1 << BDADDR_LE_PUBLIC) | (1 << BDADDR_LE_RANDOM))
#define SCAN_TYPE_DUAL (SCAN_TYPE_BREDR | SCAN_TYPE_LE)

static struct mgmt *mgmt = NULL;
static uint16_t mgmt_index = MGMT_INDEX_NONE;

static bool discovery = false;
static bool resolve_names = true;

static struct {
	uint16_t index;
	uint16_t req;
	struct mgmt_addr_info addr;
} prompt = {
	.index = MGMT_INDEX_NONE,
};


static int pending_index = 0;

#ifndef MIN
#define MIN(x, y) ((x) < (y) ? (x) : (y))
#endif

#define PROMPT_ON	COLOR_BLUE "[mgmt]" COLOR_OFF "# "

static void set_index(const char *arg)
{
	if (!arg || !strcmp(arg, "none") || !strcmp(arg, "any") ||
						!strcmp(arg, "all"))
		mgmt_index = MGMT_INDEX_NONE;
	else if(strlen(arg) > 3 && !strncasecmp(arg, "hci", 3))
		mgmt_index = atoi(&arg[3]);
	else
		mgmt_index = atoi(arg);
}

static void update_prompt(uint16_t index)
{
	char str[32];

	if (index == MGMT_INDEX_NONE)
		snprintf(str, sizeof(str), "%s# ",
					COLOR_BLUE "[mgmt]" COLOR_OFF);
	else
		snprintf(str, sizeof(str),
				COLOR_BLUE "[hci%u]" COLOR_OFF "# ", index);

	bt_shell_set_prompt(str);
}

#define print(fmt, arg...) do { \
		bt_shell_printf(fmt "\n", ## arg); \
} while (0)

#define error(fmt, arg...) do { \
		bt_shell_printf(COLOR_RED fmt "\n" COLOR_OFF, ## arg); \
} while (0)

static size_t hex2bin(const char *hexstr, uint8_t *buf, size_t buflen)
{
	size_t i, len;

	len = MIN((strlen(hexstr) / 2), buflen);
	memset(buf, 0, len);

	for (i = 0; i < len; i++)
		sscanf(hexstr + (i * 2), "%02hhX", &buf[i]);

	return len;
}

static size_t bin2hex(const uint8_t *buf, size_t buflen, char *str,
								size_t strlen)
{
	size_t i;

	for (i = 0; i < buflen && i < (strlen / 2); i++)
		sprintf(str + (i * 2), "%02x", buf[i]);

	return i;
}

static void print_eir(const uint8_t *eir, uint16_t eir_len)
{
	uint16_t parsed = 0;
	char str[33];

	while (parsed < eir_len - 1) {
		uint8_t field_len = eir[0];

		if (field_len == 0)
			break;

		parsed += field_len + 1;

		if (parsed > eir_len)
			break;

		switch (eir[1]) {
		case 0x01:
			print("Flags: 0x%02x", eir[2]);
			break;
		case 0x0d:
			print("Class of Device: 0x%02x%02x%02x",
						eir[4], eir[3], eir[2]);
			break;
		case 0x0e:
			bin2hex(eir + 2, 16, str, sizeof(str));
			print("SSP Hash C-192: %s", str);
			break;
		case 0x0f:
			bin2hex(eir + 2, 16, str, sizeof(str));
			print("SSP Rand R-192: %s", str);
			break;
		case 0x1b:
			ba2str((bdaddr_t *) (eir + 2), str);
			print("LE Device Address: %s (%s)", str,
					eir[8] ? "random" : "public");
			break;
		case 0x1c:
			print("LE Role: 0x%02x", eir[2]);
			break;
		case 0x1d:
			bin2hex(eir + 2, 16, str, sizeof(str));
			print("SSP Hash C-256: %s", str);
			break;
		case 0x1e:
			bin2hex(eir + 2, 16, str, sizeof(str));
			print("SSP Rand R-256: %s", str);
			break;
		case 0x22:
			bin2hex(eir + 2, 16, str, sizeof(str));
			print("LE SC Confirmation Value: %s", str);
			break;
		case 0x23:
			bin2hex(eir + 2, 16, str, sizeof(str));
			print("LE SC Random Value: %s", str);
			break;
		default:
			print("Type %u: %u byte%s", eir[1], field_len - 1,
					(field_len - 1) == 1 ? "" : "s");
			break;
		}

		eir += field_len + 1;
	}
}

static bool load_identity(const char *path, struct mgmt_irk_info *irk)
{
	char *addr, *key;
	unsigned int type;
	int n;
	FILE *fp;

	fp = fopen(path, "r");
	if (!fp) {
		error("Failed to open identity file: %s", strerror(errno));
		return false;
	}

	n = fscanf(fp, "%m[0-9a-f:] (type %u) %m[0-9a-f]", &addr, &type, &key);

	fclose(fp);

	if (n != 3)
		return false;

	str2ba(addr, &irk->addr.bdaddr);
	hex2bin(key, irk->val, sizeof(irk->val));

	free(addr);
	free(key);

	switch (type) {
	case 0:
		irk->addr.type = BDADDR_LE_PUBLIC;
		break;
	case 1:
		irk->addr.type = BDADDR_LE_RANDOM;
		break;
	default:
		error("Invalid address type %u", type);
		return false;
	}

	return true;
}

static void controller_error(uint16_t index, uint16_t len,
				const void *param, void *user_data)
{
	const struct mgmt_ev_controller_error *ev = param;

	if (len < sizeof(*ev)) {
		error("Too short (%u bytes) controller error event", len);
		return;
	}

	print("hci%u error 0x%02x", index, ev->error_code);
}

static void index_added(uint16_t index, uint16_t len,
				const void *param, void *user_data)
{
	print("hci%u added", index);
}

static void index_removed(uint16_t index, uint16_t len,
				const void *param, void *user_data)
{
	print("hci%u removed", index);
}

static void unconf_index_added(uint16_t index, uint16_t len,
				const void *param, void *user_data)
{
	print("hci%u added (unconfigured)", index);
}

static void unconf_index_removed(uint16_t index, uint16_t len,
				const void *param, void *user_data)
{
	print("hci%u removed (unconfigured)", index);
}

static void ext_index_added(uint16_t index, uint16_t len,
				const void *param, void *user_data)
{
	const struct mgmt_ev_ext_index_added *ev = param;

	print("hci%u added (type %u bus %u)", index, ev->type, ev->bus);
}

static void ext_index_removed(uint16_t index, uint16_t len,
				const void *param, void *user_data)
{
	const struct mgmt_ev_ext_index_removed *ev = param;

	print("hci%u removed (type %u bus %u)", index, ev->type, ev->bus);
}

static const char *options_str[] = {
				"external",
				"public-address",
};

static const char *options2str(uint32_t options)
{
	static char str[256];
	unsigned i;
	int off;

	off = 0;
	str[0] = '\0';

	for (i = 0; i < NELEM(options_str); i++) {
		if ((options & (1 << i)) != 0)
			off += snprintf(str + off, sizeof(str) - off, "%s ",
							options_str[i]);
	}

	return str;
}

static void new_config_options(uint16_t index, uint16_t len,
					const void *param, void *user_data)
{
	const uint32_t *ev = param;

	if (len < sizeof(*ev)) {
		error("Too short new_config_options event (%u)", len);
		return;
	}

	print("hci%u new_config_options: %s", index, options2str(get_le32(ev)));
}

static const char *settings_str[] = {
				"powered",
				"connectable",
				"fast-connectable",
				"discoverable",
				"bondable",
				"link-security",
				"ssp",
				"br/edr",
				"hs",
				"le",
				"advertising",
				"secure-conn",
				"debug-keys",
				"privacy",
				"configuration",
				"static-addr",
};

static const char *settings2str(uint32_t settings)
{
	static char str[256];
	unsigned i;
	int off;

	off = 0;
	str[0] = '\0';

	for (i = 0; i < NELEM(settings_str); i++) {
		if ((settings & (1 << i)) != 0)
			off += snprintf(str + off, sizeof(str) - off, "%s ",
							settings_str[i]);
	}

	return str;
}

static void new_settings(uint16_t index, uint16_t len,
					const void *param, void *user_data)
{
	const uint32_t *ev = param;

	if (len < sizeof(*ev)) {
		error("Too short new_settings event (%u)", len);
		return;
	}

	print("hci%u new_settings: %s", index, settings2str(get_le32(ev)));
}

static void discovering(uint16_t index, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_ev_discovering *ev = param;

	if (len < sizeof(*ev)) {
		error("Too short (%u bytes) discovering event", len);
		return;
	}

	print("hci%u type %u discovering %s", index, ev->type,
					ev->discovering ? "on" : "off");

	if (ev->discovering == 0 && discovery)
		return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static void new_link_key(uint16_t index, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_ev_new_link_key *ev = param;
	char addr[18];

	if (len != sizeof(*ev)) {
		error("Invalid new_link_key length (%u bytes)", len);
		return;
	}

	ba2str(&ev->key.addr.bdaddr, addr);
	print("hci%u new_link_key %s type 0x%02x pin_len %d store_hint %u",
		index, addr, ev->key.type, ev->key.pin_len, ev->store_hint);
}

static const char *typestr(uint8_t type)
{
	static const char *str[] = { "BR/EDR", "LE Public", "LE Random" };

	if (type <= BDADDR_LE_RANDOM)
		return str[type];

	return "(unknown)";
}

static void connected(uint16_t index, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_ev_device_connected *ev = param;
	uint16_t eir_len;
	char addr[18];

	if (len < sizeof(*ev)) {
		error("Invalid connected event length (%u bytes)", len);
		return;
	}

	eir_len = get_le16(&ev->eir_len);
	if (len != sizeof(*ev) + eir_len) {
		error("Invalid connected event length (%u != eir_len %u)",
								len, eir_len);
		return;
	}

	ba2str(&ev->addr.bdaddr, addr);
	print("hci%u %s type %s connected eir_len %u", index, addr,
					typestr(ev->addr.type), eir_len);
}

static void disconnected(uint16_t index, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_ev_device_disconnected *ev = param;
	char addr[18];
	uint8_t reason;

	if (len < sizeof(struct mgmt_addr_info)) {
		error("Invalid disconnected event length (%u bytes)", len);
		return;
	}

	if (len < sizeof(*ev))
		reason = MGMT_DEV_DISCONN_UNKNOWN;
	else
		reason = ev->reason;

	ba2str(&ev->addr.bdaddr, addr);
	print("hci%u %s type %s disconnected with reason %u",
			index, addr, typestr(ev->addr.type), reason);
}

static void conn_failed(uint16_t index, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_ev_connect_failed *ev = param;
	char addr[18];

	if (len != sizeof(*ev)) {
		error("Invalid connect_failed event length (%u bytes)", len);
		return;
	}

	ba2str(&ev->addr.bdaddr, addr);
	print("hci%u %s type %s connect failed (status 0x%02x, %s)",
			index, addr, typestr(ev->addr.type), ev->status,
			mgmt_errstr(ev->status));
}

static void auth_failed(uint16_t index, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_ev_auth_failed *ev = param;
	char addr[18];

	if (len != sizeof(*ev)) {
		error("Invalid auth_failed event length (%u bytes)", len);
		return;
	}

	ba2str(&ev->addr.bdaddr, addr);
	print("hci%u %s auth failed with status 0x%02x (%s)",
			index, addr, ev->status, mgmt_errstr(ev->status));
}

static void class_of_dev_changed(uint16_t index, uint16_t len,
					const void *param, void *user_data)
{
	const struct mgmt_ev_class_of_dev_changed *ev = param;

	if (len != sizeof(*ev)) {
		error("Invalid class_of_dev_changed length (%u bytes)", len);
		return;
	}

	print("hci%u class of device changed: 0x%02x%02x%02x", index,
			ev->dev_class[2], ev->dev_class[1], ev->dev_class[0]);
}

static void local_name_changed(uint16_t index, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_ev_local_name_changed *ev = param;

	if (len != sizeof(*ev)) {
		error("Invalid local_name_changed length (%u bytes)", len);
		return;
	}

	print("hci%u name changed: %s", index, ev->name);
}

static void confirm_name_rsp(uint8_t status, uint16_t len,
					const void *param, void *user_data)
{
	const struct mgmt_rp_confirm_name *rp = param;
	char addr[18];

	if (len == 0 && status != 0) {
		error("confirm_name failed with status 0x%02x (%s)", status,
							mgmt_errstr(status));
		return;
	}

	if (len != sizeof(*rp)) {
		error("confirm_name rsp length %u instead of %zu",
							len, sizeof(*rp));
		return;
	}

	ba2str(&rp->addr.bdaddr, addr);

	if (status != 0)
		error("confirm_name for %s failed: 0x%02x (%s)",
			addr, status, mgmt_errstr(status));
	else
		print("confirm_name succeeded for %s", addr);
}

static char *eir_get_name(const uint8_t *eir, uint16_t eir_len)
{
	uint8_t parsed = 0;

	if (eir_len < 2)
		return NULL;

	while (parsed < eir_len - 1) {
		uint8_t field_len = eir[0];

		if (field_len == 0)
			break;

		parsed += field_len + 1;

		if (parsed > eir_len)
			break;

		/* Check for short of complete name */
		if (eir[1] == 0x09 || eir[1] == 0x08)
			return strndup((char *) &eir[2], field_len - 1);

		eir += field_len + 1;
	}

	return NULL;
}

static unsigned int eir_get_flags(const uint8_t *eir, uint16_t eir_len)
{
	uint8_t parsed = 0;

	if (eir_len < 2)
		return 0;

	while (parsed < eir_len - 1) {
		uint8_t field_len = eir[0];

		if (field_len == 0)
			break;

		parsed += field_len + 1;

		if (parsed > eir_len)
			break;

		/* Check for flags */
		if (eir[1] == 0x01)
			return eir[2];

		eir += field_len + 1;
	}

	return 0;
}

static void device_found(uint16_t index, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_ev_device_found *ev = param;
	struct mgmt *mgmt = user_data;
	uint16_t eir_len;
	uint32_t flags;

	if (len < sizeof(*ev)) {
		error("Too short device_found length (%u bytes)", len);
		return;
	}

	flags = btohl(ev->flags);

	eir_len = get_le16(&ev->eir_len);
	if (len != sizeof(*ev) + eir_len) {
		error("dev_found: expected %zu bytes, got %u bytes",
						sizeof(*ev) + eir_len, len);
		return;
	}

	if (discovery) {
		char addr[18], *name;

		ba2str(&ev->addr.bdaddr, addr);
		print("hci%u dev_found: %s type %s rssi %d "
			"flags 0x%04x ", index, addr,
			typestr(ev->addr.type), ev->rssi, flags);

		if (ev->addr.type != BDADDR_BREDR)
			print("AD flags 0x%02x ",
					eir_get_flags(ev->eir, eir_len));

		name = eir_get_name(ev->eir, eir_len);
		if (name)
			print("name %s", name);
		else
			print("eir_len %u", eir_len);

		free(name);
	}

	if (discovery && (flags & MGMT_DEV_FOUND_CONFIRM_NAME)) {
		struct mgmt_cp_confirm_name cp;

		memset(&cp, 0, sizeof(cp));
		memcpy(&cp.addr, &ev->addr, sizeof(cp.addr));
		if (resolve_names)
			cp.name_known = 0;
		else
			cp.name_known = 1;

		mgmt_reply(mgmt, MGMT_OP_CONFIRM_NAME, index, sizeof(cp), &cp,
						confirm_name_rsp, NULL, NULL);
	}
}

static void pin_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	if (status != 0) {
		error("PIN Code reply failed with status 0x%02x (%s)",
						status, mgmt_errstr(status));
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	print("PIN Reply successful");
}

static int mgmt_pin_reply(uint16_t index, const struct mgmt_addr_info *addr,
					const char *pin, size_t len)
{
	struct mgmt_cp_pin_code_reply cp;

	memset(&cp, 0, sizeof(cp));
	memcpy(&cp.addr, addr, sizeof(cp.addr));
	cp.pin_len = len;
	memcpy(cp.pin_code, pin, len);

	return mgmt_reply(mgmt, MGMT_OP_PIN_CODE_REPLY, index,
				sizeof(cp), &cp, pin_rsp, NULL, NULL);
}

static void pin_neg_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	if (status != 0) {
		error("PIN Neg reply failed with status 0x%02x (%s)",
						status, mgmt_errstr(status));
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	print("PIN Negative Reply successful");
}

static int mgmt_pin_neg_reply(uint16_t index, const struct mgmt_addr_info *addr)
{
	struct mgmt_cp_pin_code_neg_reply cp;

	memset(&cp, 0, sizeof(cp));
	memcpy(&cp.addr, addr, sizeof(cp.addr));

	return mgmt_reply(mgmt, MGMT_OP_PIN_CODE_NEG_REPLY, index,
				sizeof(cp), &cp, pin_neg_rsp, NULL, NULL);
}

static void confirm_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	if (status != 0) {
		error("User Confirm reply failed. status 0x%02x (%s)",
						status, mgmt_errstr(status));
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	print("User Confirm Reply successful");
}

static int mgmt_confirm_reply(uint16_t index, const struct mgmt_addr_info *addr)
{
	struct mgmt_cp_user_confirm_reply cp;

	memset(&cp, 0, sizeof(cp));
	memcpy(&cp.addr, addr, sizeof(*addr));

	return mgmt_reply(mgmt, MGMT_OP_USER_CONFIRM_REPLY, index,
				sizeof(cp), &cp, confirm_rsp, NULL, NULL);
}

static void confirm_neg_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	if (status != 0) {
		error("Confirm Neg reply failed. status 0x%02x (%s)",
						status, mgmt_errstr(status));
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	print("User Confirm Negative Reply successful");
}

static int mgmt_confirm_neg_reply(uint16_t index,
					const struct mgmt_addr_info *addr)
{
	struct mgmt_cp_user_confirm_reply cp;

	memset(&cp, 0, sizeof(cp));
	memcpy(&cp.addr, addr, sizeof(*addr));

	return mgmt_reply(mgmt, MGMT_OP_USER_CONFIRM_NEG_REPLY, index,
				sizeof(cp), &cp, confirm_neg_rsp, NULL, NULL);
}

static void passkey_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	if (status != 0) {
		error("User Passkey reply failed. status 0x%02x (%s)",
						status, mgmt_errstr(status));
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	print("User Passkey Reply successful");
}

static int mgmt_passkey_reply(uint16_t index, const struct mgmt_addr_info *addr,
						uint32_t passkey)
{
	struct mgmt_cp_user_passkey_reply cp;

	memset(&cp, 0, sizeof(cp));
	memcpy(&cp.addr, addr, sizeof(*addr));
	put_le32(passkey, &cp.passkey);

	return mgmt_reply(mgmt, MGMT_OP_USER_PASSKEY_REPLY, index,
				sizeof(cp), &cp, passkey_rsp, NULL, NULL);
}

static void passkey_neg_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	if (status != 0) {
		error("Passkey Neg reply failed. status 0x%02x (%s)",
						status, mgmt_errstr(status));
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	print("User Passkey Negative Reply successful");
}

static int mgmt_passkey_neg_reply(uint16_t index,
					const struct mgmt_addr_info *addr)
{
	struct mgmt_cp_user_passkey_reply cp;

	memset(&cp, 0, sizeof(cp));
	memcpy(&cp.addr, addr, sizeof(*addr));

	return mgmt_reply(mgmt, MGMT_OP_USER_PASSKEY_NEG_REPLY, index,
				sizeof(cp), &cp, passkey_neg_rsp, NULL, NULL);
}

static void prompt_input(const char *input, void *user_data)
{
	size_t len;

	len = strlen(input);

	switch (prompt.req) {
	case MGMT_EV_PIN_CODE_REQUEST:
		if (len)
			mgmt_pin_reply(prompt.index, &prompt.addr, input, len);
		else
			mgmt_pin_neg_reply(prompt.index, &prompt.addr);
		break;
	case MGMT_EV_USER_PASSKEY_REQUEST:
		if (strlen(input) > 0)
			mgmt_passkey_reply(prompt.index, &prompt.addr,
								atoi(input));
		else
			mgmt_passkey_neg_reply(prompt.index,
								&prompt.addr);
		break;
	case MGMT_EV_USER_CONFIRM_REQUEST:
		if (input[0] == 'y' || input[0] == 'Y')
			mgmt_confirm_reply(prompt.index, &prompt.addr);
		else
			mgmt_confirm_neg_reply(prompt.index, &prompt.addr);
		break;
	}
}

static void ask(uint16_t index, uint16_t req, const struct mgmt_addr_info *addr,
						const char *fmt, ...)
{
	char msg[256];
	va_list ap;
	int off;

	prompt.index = index;
	prompt.req = req;
	memcpy(&prompt.addr, addr, sizeof(*addr));

	va_start(ap, fmt);
	off = vsnprintf(msg, sizeof(msg), fmt, ap);
	va_end(ap);

	snprintf(msg + off, sizeof(msg) - off, " %s ",
					COLOR_BOLDGRAY ">>" COLOR_OFF);

	bt_shell_prompt_input("", msg, prompt_input, NULL);
}

static void request_pin(uint16_t index, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_ev_pin_code_request *ev = param;
	char addr[18];

	if (len != sizeof(*ev)) {
		error("Invalid pin_code request length (%u bytes)", len);
		return;
	}

	ba2str(&ev->addr.bdaddr, addr);
	print("hci%u %s request PIN", index, addr);

	ask(index, MGMT_EV_PIN_CODE_REQUEST, &ev->addr,
				"PIN Request (press enter to reject)");
}

static void user_confirm(uint16_t index, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_ev_user_confirm_request *ev = param;
	uint32_t val;
	char addr[18];

	if (len != sizeof(*ev)) {
		error("Invalid user_confirm request length (%u)", len);
		return;
	}

	ba2str(&ev->addr.bdaddr, addr);
	val = get_le32(&ev->value);

	print("hci%u %s User Confirm %06u hint %u", index, addr,
							val, ev->confirm_hint);

	if (ev->confirm_hint)
		ask(index, MGMT_EV_USER_CONFIRM_REQUEST, &ev->addr,
				"Accept pairing with %s (yes/no)", addr);
	else
		ask(index, MGMT_EV_USER_CONFIRM_REQUEST, &ev->addr,
			"Confirm value %06u for %s (yes/no)", val, addr);
}

static void request_passkey(uint16_t index, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_ev_user_passkey_request *ev = param;
	char addr[18];

	if (len != sizeof(*ev)) {
		error("Invalid passkey request length (%u bytes)", len);
		return;
	}

	ba2str(&ev->addr.bdaddr, addr);
	print("hci%u %s request passkey", index, addr);

	ask(index, MGMT_EV_USER_PASSKEY_REQUEST, &ev->addr,
			"Passkey Request (press enter to reject)");
}

static void passkey_notify(uint16_t index, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_ev_passkey_notify *ev = param;
	char addr[18];

	if (len != sizeof(*ev)) {
		error("Invalid passkey request length (%u bytes)", len);
		return;
	}

	ba2str(&ev->addr.bdaddr, addr);
	print("hci%u %s request passkey", index, addr);

	print("Passkey Notify: %06u (entered %u)", get_le32(&ev->passkey),
								ev->entered);
}

static void local_oob_data_updated(uint16_t index, uint16_t len,
					const void *param, void *user_data)
{
	const struct mgmt_ev_local_oob_data_updated *ev = param;
	uint16_t eir_len;

	if (len < sizeof(*ev)) {
		error("Too small (%u bytes) local_oob_updated event", len);
		return;
	}

	eir_len = le16_to_cpu(ev->eir_len);
	if (len != sizeof(*ev) + eir_len) {
		error("local_oob_updated: expected %zu bytes, got %u bytes",
						sizeof(*ev) + eir_len, len);
		return;
	}

	print("hci%u oob data updated: type %u len %u", index,
						ev->type, eir_len);
}

static void advertising_added(uint16_t index, uint16_t len,
					const void *param, void *user_data)
{
	const struct mgmt_ev_advertising_added *ev = param;

	if (len < sizeof(*ev)) {
		error("Too small (%u bytes) advertising_added event", len);
		return;
	}

	print("hci%u advertising_added: instance %u", index, ev->instance);
}

static void advertising_removed(uint16_t index, uint16_t len,
					const void *param, void *user_data)
{
	const struct mgmt_ev_advertising_removed *ev = param;

	if (len < sizeof(*ev)) {
		error("Too small (%u bytes) advertising_removed event", len);
		return;
	}

	print("hci%u advertising_removed: instance %u", index, ev->instance);
}

static void version_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_rp_read_version *rp = param;

	if (status != 0) {
		error("Reading mgmt version failed with status 0x%02x (%s)",
						status, mgmt_errstr(status));
		goto done;
	}

	if (len < sizeof(*rp)) {
		error("Too small version reply (%u bytes)", len);
		goto done;
	}

	print("MGMT Version %u, revision %u", rp->version,
						get_le16(&rp->revision));

done:
	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static void cmd_version(int argc, char **argv)
{
	if (mgmt_send(mgmt, MGMT_OP_READ_VERSION, MGMT_INDEX_NONE,
				0, NULL, version_rsp, NULL, NULL) == 0) {
		error("Unable to send read_version cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void commands_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_rp_read_commands *rp = param;
	uint16_t num_commands, num_events;
	const uint16_t *opcode;
	size_t expected_len;
	int i;

	if (status != 0) {
		error("Read Supported Commands failed: status 0x%02x (%s)",
						status, mgmt_errstr(status));
		goto done;
	}

	if (len < sizeof(*rp)) {
		error("Too small commands reply (%u bytes)", len);
		goto done;
	}

	num_commands = get_le16(&rp->num_commands);
	num_events = get_le16(&rp->num_events);

	expected_len = sizeof(*rp) + num_commands * sizeof(uint16_t) +
						num_events * sizeof(uint16_t);

	if (len < expected_len) {
		error("Too small commands reply (%u != %zu)",
							len, expected_len);
		goto done;
	}

	opcode = rp->opcodes;

	print("%u commands:", num_commands);
	for (i = 0; i < num_commands; i++) {
		uint16_t op = get_le16(opcode++);
		print("\t%s (0x%04x)", mgmt_opstr(op), op);
	}

	print("%u events:", num_events);
	for (i = 0; i < num_events; i++) {
		uint16_t ev = get_le16(opcode++);
		print("\t%s (0x%04x)", mgmt_evstr(ev), ev);
	}

done:
	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static void cmd_commands(int argc,
								char **argv)
{
	if (mgmt_send(mgmt, MGMT_OP_READ_COMMANDS, MGMT_INDEX_NONE,
				0, NULL, commands_rsp, NULL, NULL) == 0) {
		error("Unable to send read_commands cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void config_info_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_rp_read_config_info *rp = param;
	uint16_t index = PTR_TO_UINT(user_data);
	uint32_t supported_options, missing_options;

	if (status != 0) {
		error("Reading hci%u config failed with status 0x%02x (%s)",
					index, status, mgmt_errstr(status));
		goto done;
	}

	if (len < sizeof(*rp)) {
		error("Too small info reply (%u bytes)", len);
		goto done;
	}

	print("hci%u:\tUnconfigured controller", index);

	print("\tmanufacturer %u", le16_to_cpu(rp->manufacturer));

	supported_options = le32_to_cpu(rp->supported_options);
	print("\tsupported options: %s", options2str(supported_options));

	missing_options = le32_to_cpu(rp->missing_options);
	print("\tmissing options: %s", options2str(missing_options));

done:
	pending_index--;

	if (pending_index > 0)
		return;

	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static void unconf_index_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_rp_read_unconf_index_list *rp = param;
	uint16_t count;
	unsigned int i;

	if (status != 0) {
		error("Reading index list failed with status 0x%02x (%s)",
						status, mgmt_errstr(status));
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	if (len < sizeof(*rp)) {
		error("Too small index list reply (%u bytes)", len);
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	count = le16_to_cpu(rp->num_controllers);

	if (len < sizeof(*rp) + count * sizeof(uint16_t)) {
		error("Index count (%u) doesn't match reply length (%u)",
								count, len);
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	print("Unconfigured index list with %u item%s",
					count, count != 1 ? "s" : "");

	for (i = 0; i < count; i++) {
		uint16_t index = le16_to_cpu(rp->index[i]);

		if (!mgmt_send(mgmt, MGMT_OP_READ_CONFIG_INFO, index, 0, NULL,
				config_info_rsp, UINT_TO_PTR(index), NULL)) {
			error("Unable to send read_config_info cmd");
			return bt_shell_noninteractive_quit(EXIT_FAILURE);
		}

		pending_index++;
	}

	if (!count)
		bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static void cmd_config(int argc, char **argv)
{
	if (mgmt_index == MGMT_INDEX_NONE) {
		if (!mgmt_send(mgmt, MGMT_OP_READ_UNCONF_INDEX_LIST,
					MGMT_INDEX_NONE, 0, NULL,
					unconf_index_rsp, mgmt, NULL)) {
			error("Unable to send unconf_index_list cmd");
			return bt_shell_noninteractive_quit(EXIT_FAILURE);
		}

		return;
	}

	if (!mgmt_send(mgmt, MGMT_OP_READ_CONFIG_INFO, mgmt_index, 0, NULL,
				config_info_rsp, UINT_TO_PTR(index), NULL)) {
		error("Unable to send read_config_info cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void config_options_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_rp_read_config_info *rp = param;
	uint16_t index = PTR_TO_UINT(user_data);
	uint32_t supported_options, missing_options;

	if (status != 0) {
		error("Reading hci%u config failed with status 0x%02x (%s)",
					index, status, mgmt_errstr(status));
		goto done;
	}

	if (len < sizeof(*rp)) {
		error("Too small info reply (%u bytes)", len);
		goto done;
	}

	print("hci%u:\tConfiguration options", index);

	supported_options = le32_to_cpu(rp->supported_options);
	print("\tsupported options: %s", options2str(supported_options));

	missing_options = le32_to_cpu(rp->missing_options);
	print("\tmissing options: %s", options2str(missing_options));

done:
	pending_index--;

	if (pending_index > 0)
		return;

	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static void info_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_rp_read_info *rp = param;
	uint16_t index = PTR_TO_UINT(user_data);
	uint32_t supported_settings, current_settings;
	char addr[18];

	if (status != 0) {
		error("Reading hci%u info failed with status 0x%02x (%s)",
					index, status, mgmt_errstr(status));
		goto done;
	}

	if (len < sizeof(*rp)) {
		error("Too small info reply (%u bytes)", len);
		goto done;
	}

	print("hci%u:\tPrimary controller", index);

	ba2str(&rp->bdaddr, addr);
	print("\taddr %s version %u manufacturer %u class 0x%02x%02x%02x",
			addr, rp->version, le16_to_cpu(rp->manufacturer),
			rp->dev_class[2], rp->dev_class[1], rp->dev_class[0]);

	supported_settings = le32_to_cpu(rp->supported_settings);
	print("\tsupported settings: %s", settings2str(supported_settings));

	current_settings = le32_to_cpu(rp->current_settings);
	print("\tcurrent settings: %s", settings2str(current_settings));

	print("\tname %s", rp->name);
	print("\tshort name %s", rp->short_name);

	if (supported_settings & MGMT_SETTING_CONFIGURATION) {
		if (!mgmt_send(mgmt, MGMT_OP_READ_CONFIG_INFO,
					index, 0, NULL, config_options_rsp,
					UINT_TO_PTR(index), NULL)) {
			error("Unable to send read_config cmd");
			goto done;
		}
		return;
	}

done:
	pending_index--;

	if (pending_index > 0)
		return;

	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static void ext_info_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_rp_read_ext_info *rp = param;
	uint16_t index = PTR_TO_UINT(user_data);
	uint32_t supported_settings, current_settings;
	char addr[18];

	if (status != 0) {
		error("Reading hci%u info failed with status 0x%02x (%s)",
					index, status, mgmt_errstr(status));
		goto done;
	}

	if (len < sizeof(*rp)) {
		error("Too small info reply (%u bytes)", len);
		goto done;
	}

	print("hci%u:\tPrimary controller", index);

	ba2str(&rp->bdaddr, addr);
	print("\taddr %s version %u manufacturer %u",
			addr, rp->version, le16_to_cpu(rp->manufacturer));

	supported_settings = le32_to_cpu(rp->supported_settings);
	print("\tsupported settings: %s", settings2str(supported_settings));

	current_settings = le32_to_cpu(rp->current_settings);
	print("\tcurrent settings: %s", settings2str(current_settings));

	if (supported_settings & MGMT_SETTING_CONFIGURATION) {
		if (!mgmt_send(mgmt, MGMT_OP_READ_CONFIG_INFO,
					index, 0, NULL, config_options_rsp,
					UINT_TO_PTR(index), NULL)) {
			error("Unable to send read_config cmd");
			goto done;
		}
		return;
	}

done:
	pending_index--;

	if (pending_index > 0)
		return;

	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static void index_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_rp_read_index_list *rp = param;
	struct mgmt *mgmt = user_data;
	uint16_t count;
	unsigned int i;

	if (status != 0) {
		error("Reading index list failed with status 0x%02x (%s)",
						status, mgmt_errstr(status));
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	if (len < sizeof(*rp)) {
		error("Too small index list reply (%u bytes)", len);
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	count = le16_to_cpu(rp->num_controllers);

	if (len < sizeof(*rp) + count * sizeof(uint16_t)) {
		error("Index count (%u) doesn't match reply length (%u)",
								count, len);
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	print("Index list with %u item%s", count, count != 1 ? "s" : "");

	for (i = 0; i < count; i++) {
		uint16_t index = le16_to_cpu(rp->index[i]);

		if (!mgmt_send(mgmt, MGMT_OP_READ_INFO, index, 0, NULL,
					info_rsp, UINT_TO_PTR(index), NULL)) {
			error("Unable to send read_info cmd");
			return bt_shell_noninteractive_quit(EXIT_FAILURE);
		}

		pending_index++;
	}

	if (!count)
		bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static void cmd_info(int argc, char **argv)
{
	if (mgmt_index == MGMT_INDEX_NONE) {
		if (!mgmt_send(mgmt, MGMT_OP_READ_INDEX_LIST,
					MGMT_INDEX_NONE, 0, NULL,
					index_rsp, mgmt, NULL)) {
			error("Unable to send index_list cmd");
			return bt_shell_noninteractive_quit(EXIT_FAILURE);
		}

		return;
	}

	if (!mgmt_send(mgmt, MGMT_OP_READ_INFO, mgmt_index, 0, NULL, info_rsp,
					UINT_TO_PTR(mgmt_index), NULL)) {
		error("Unable to send read_info cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void ext_index_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_rp_read_ext_index_list *rp = param;
	uint16_t count, index_filter = PTR_TO_UINT(user_data);
	unsigned int i;

	if (status != 0) {
		error("Reading ext index list failed with status 0x%02x (%s)",
						status, mgmt_errstr(status));
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	if (len < sizeof(*rp)) {
		error("Too small ext index list reply (%u bytes)", len);
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	count = get_le16(&rp->num_controllers);

	if (len < sizeof(*rp) + count * (sizeof(uint16_t) + sizeof(uint8_t))) {
		error("Index count (%u) doesn't match reply length (%u)",
								count, len);
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	print("Extended index list with %u item%s",
					count, count != 1 ? "s" : "");

	for (i = 0; i < count; i++) {
		uint16_t index = le16_to_cpu(rp->entry[i].index);
		char *busstr = hci_bustostr(rp->entry[i].bus);

		if (index_filter != MGMT_INDEX_NONE && index_filter != index)
			continue;

		switch (rp->entry[i].type) {
		case 0x00:
			print("Primary controller (hci%u,%s)", index, busstr);
			if (!mgmt_send(mgmt, MGMT_OP_READ_EXT_INFO,
						index, 0, NULL, ext_info_rsp,
						UINT_TO_PTR(index), NULL)) {
				error("Unable to send read_ext_info cmd");
				return bt_shell_noninteractive_quit(EXIT_FAILURE);
			}
			pending_index++;
			break;
		case 0x01:
			print("Unconfigured controller (hci%u,%s)",
								index, busstr);
			if (!mgmt_send(mgmt, MGMT_OP_READ_CONFIG_INFO,
						index, 0, NULL, config_info_rsp,
						UINT_TO_PTR(index), NULL)) {
				error("Unable to send read_config cmd");
				return bt_shell_noninteractive_quit(EXIT_FAILURE);
			}
			pending_index++;
			break;
		case 0x02:
			print("AMP controller (hci%u,%s)", index, busstr);
			break;
		default:
			print("Type %u controller (hci%u,%s)",
					rp->entry[i].type, index, busstr);
			break;
		}
	}

	print("");

	if (!count)
		bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static void cmd_extinfo(
						int argc, char **argv)
{
	if (!mgmt_send(mgmt, MGMT_OP_READ_EXT_INDEX_LIST,
				MGMT_INDEX_NONE, 0, NULL,
				ext_index_rsp, UINT_TO_PTR(index), NULL)) {
		error("Unable to send ext_index_list cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void auto_power_enable_rsp(uint8_t status, uint16_t len,
					const void *param, void *user_data)
{
	uint16_t index = PTR_TO_UINT(user_data);

	print("Successfully enabled controller with index %u", index);

	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static void auto_power_info_rsp(uint8_t status, uint16_t len,
					const void *param, void *user_data)
{
	const struct mgmt_rp_read_info *rp = param;
	uint16_t index = PTR_TO_UINT(user_data);
	uint32_t supported_settings, current_settings, missing_settings;
	uint8_t val = 0x01;

	if (status) {
		error("Reading info failed with status 0x%02x (%s)",
						status, mgmt_errstr(status));
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	supported_settings = le32_to_cpu(rp->supported_settings);
	current_settings = le32_to_cpu(rp->current_settings);
	missing_settings = current_settings ^ supported_settings;

	if (missing_settings & MGMT_SETTING_BREDR)
		mgmt_send(mgmt, MGMT_OP_SET_BREDR, index, sizeof(val), &val,
							NULL, NULL, NULL);

	if (missing_settings & MGMT_SETTING_SSP)
		mgmt_send(mgmt, MGMT_OP_SET_SSP, index, sizeof(val), &val,
							NULL, NULL, NULL);

	if (missing_settings & MGMT_SETTING_LE)
		mgmt_send(mgmt, MGMT_OP_SET_LE, index, sizeof(val), &val,
							NULL, NULL, NULL);

	if (missing_settings & MGMT_SETTING_SECURE_CONN)
		mgmt_send(mgmt, MGMT_OP_SET_SECURE_CONN, index,
							sizeof(val), &val,
							NULL, NULL, NULL);

	if (missing_settings & MGMT_SETTING_BONDABLE)
		mgmt_send(mgmt, MGMT_OP_SET_BONDABLE, index, sizeof(val), &val,
							NULL, NULL, NULL);

	if (current_settings & MGMT_SETTING_POWERED)
		return bt_shell_noninteractive_quit(EXIT_SUCCESS);

	if (!mgmt_send(mgmt, MGMT_OP_SET_POWERED, index, sizeof(val), &val,
						auto_power_enable_rsp,
						UINT_TO_PTR(index), NULL)) {
		error("Unable to send set powerd cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void auto_power_index_evt(uint16_t index, uint16_t len,
					const void *param, void *user_data)
{
	uint16_t index_filter = PTR_TO_UINT(user_data);

	if (index != index_filter)
		return;

	print("New controller with index %u", index);

	if (!mgmt_send(mgmt, MGMT_OP_READ_INFO, index, 0, NULL,
						auto_power_info_rsp,
						UINT_TO_PTR(index), NULL)) {
		error("Unable to send read info cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void auto_power_index_rsp(uint8_t status, uint16_t len,
					const void *param, void *user_data)
{
	const struct mgmt_rp_read_index_list *rp = param;
	uint16_t index = PTR_TO_UINT(user_data);
	uint16_t i, count;
	bool found = false;

	if (status) {
		error("Reading index list failed with status 0x%02x (%s)",
						status, mgmt_errstr(status));
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	count = le16_to_cpu(rp->num_controllers);
	for (i = 0; i < count; i++) {
		if (le16_to_cpu(rp->index[i]) == index)
			found = true;
	}

	if (!found) {
		print("Waiting for index %u to appear", index);

		mgmt_register(mgmt, MGMT_EV_INDEX_ADDED, index,
						auto_power_index_evt,
						UINT_TO_PTR(index), NULL);
		return;
	}

	print("Found controller with index %u", index);

	if (!mgmt_send(mgmt, MGMT_OP_READ_INFO, index, 0, NULL,
						auto_power_info_rsp,
						UINT_TO_PTR(index), NULL)) {
		error("Unable to send read info cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void cmd_auto_power(int argc, char **argv)
{
	int index;

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	if (!mgmt_send(mgmt, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0, NULL,
						auto_power_index_rsp,
						UINT_TO_PTR(index), NULL)) {
		error("Unable to send read index list cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

/* Wrapper to get the index and opcode to the response callback */
struct command_data {
	uint16_t id;
	uint16_t op;
	void (*callback) (uint16_t id, uint16_t op, uint8_t status,
					uint16_t len, const void *param);
};

static void cmd_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	struct command_data *data = user_data;

	data->callback(data->op, data->id, status, len, param);
}

static unsigned int send_cmd(struct mgmt *mgmt, uint16_t op, uint16_t id,
				uint16_t len, const void *param,
				void (*cb)(uint16_t id, uint16_t op,
						uint8_t status, uint16_t len,
						const void *param))
{
	struct command_data *data;
	unsigned int send_id;

	data = new0(struct command_data, 1);
	if (!data)
		return 0;

	data->id = id;
	data->op = op;
	data->callback = cb;

	send_id = mgmt_send(mgmt, op, id, len, param, cmd_rsp, data, free);
	if (send_id == 0)
		free(data);

	return send_id;
}

static void setting_rsp(uint16_t op, uint16_t id, uint8_t status, uint16_t len,
							const void *param)
{
	const uint32_t *rp = param;

	if (status != 0) {
		error("%s for hci%u failed with status 0x%02x (%s)",
			mgmt_opstr(op), id, status, mgmt_errstr(status));
		goto done;
	}

	if (len < sizeof(*rp)) {
		error("Too small %s response (%u bytes)",
							mgmt_opstr(op), len);
		goto done;
	}

	print("hci%u %s complete, settings: %s", id, mgmt_opstr(op),
						settings2str(get_le32(rp)));

done:
	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static bool parse_setting(int argc, char **argv, uint8_t *val)
{
	if (strcasecmp(argv[1], "on") == 0 || strcasecmp(argv[1], "yes") == 0)
		*val = 1;
	else if (strcasecmp(argv[1], "off") == 0)
		*val = 0;
	else
		*val = atoi(argv[1]);
	return true;
}

static void cmd_setting(uint16_t op, int argc, char **argv)
{
	int index;
	uint8_t val;

	if (parse_setting(argc, argv, &val) == false)
		return bt_shell_noninteractive_quit(EXIT_FAILURE);

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	if (send_cmd(mgmt, op, index, sizeof(val), &val, setting_rsp) == 0) {
		error("Unable to send %s cmd", mgmt_opstr(op));
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void cmd_power(int argc, char **argv)
{
	cmd_setting(MGMT_OP_SET_POWERED, argc, argv);
}

static void cmd_discov(int argc, char **argv)
{
	struct mgmt_cp_set_discoverable cp;
	uint16_t index;

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

	if (strcasecmp(argv[1], "on") == 0 || strcasecmp(argv[1], "yes") == 0)
		cp.val = 1;
	else if (strcasecmp(argv[1], "off") == 0)
		cp.val = 0;
	else if (strcasecmp(argv[1], "limited") == 0)
		cp.val = 2;
	else
		cp.val = atoi(argv[1]);

	if (argc > 2)
		cp.timeout = htobs(atoi(argv[2]));

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	if (send_cmd(mgmt, MGMT_OP_SET_DISCOVERABLE, index, sizeof(cp), &cp,
							setting_rsp) == 0) {
		error("Unable to send set_discoverable cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void cmd_connectable(int argc, char **argv)
{
	cmd_setting(MGMT_OP_SET_CONNECTABLE, argc, argv);
}

static void cmd_fast_conn(int argc, char **argv)
{
	cmd_setting(MGMT_OP_SET_FAST_CONNECTABLE, argc, argv);
}

static void cmd_bondable(int argc, char **argv)
{
	cmd_setting(MGMT_OP_SET_BONDABLE, argc, argv);
}

static void cmd_linksec(int argc, char **argv)
{
	cmd_setting(MGMT_OP_SET_LINK_SECURITY, argc, argv);
}

static void cmd_ssp(int argc, char **argv)
{
	cmd_setting(MGMT_OP_SET_SSP, argc, argv);
}

static void cmd_sc(int argc, char **argv)
{
	uint8_t val;
	uint16_t index;

	if (strcasecmp(argv[1], "on") == 0 || strcasecmp(argv[1], "yes") == 0)
		val = 1;
	else if (strcasecmp(argv[1], "off") == 0)
		val = 0;
	else if (strcasecmp(argv[1], "only") == 0)
		val = 2;
	else
		val = atoi(argv[1]);

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	if (send_cmd(mgmt, MGMT_OP_SET_SECURE_CONN, index,
					sizeof(val), &val, setting_rsp) == 0) {
		error("Unable to send set_secure_conn cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void cmd_hs(int argc, char **argv)
{
	cmd_setting(MGMT_OP_SET_HS, argc, argv);
}

static void cmd_le(int argc, char **argv)
{
	cmd_setting(MGMT_OP_SET_LE, argc, argv);
}

static void cmd_advertising(int argc, char **argv)
{
	cmd_setting(MGMT_OP_SET_ADVERTISING, argc, argv);
}

static void cmd_bredr(int argc, char **argv)
{
	cmd_setting(MGMT_OP_SET_BREDR, argc, argv);
}

static void cmd_privacy(int argc, char **argv)
{
	struct mgmt_cp_set_privacy cp;
	uint16_t index;

	if (parse_setting(argc, argv, &cp.privacy) == false)
		return bt_shell_noninteractive_quit(EXIT_FAILURE);

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	if (argc > 2) {
		if (hex2bin(argv[2], cp.irk,
					sizeof(cp.irk)) != sizeof(cp.irk)) {
			error("Invalid key format");
			return bt_shell_noninteractive_quit(EXIT_FAILURE);
		}
	} else {
		int fd;

		fd = open("/dev/urandom", O_RDONLY);
		if (fd < 0) {
			error("open(/dev/urandom): %s", strerror(errno));
			return bt_shell_noninteractive_quit(EXIT_FAILURE);
		}

		if (read(fd, cp.irk, sizeof(cp.irk)) != sizeof(cp.irk)) {
			error("Reading from urandom failed");
			close(fd);
			return bt_shell_noninteractive_quit(EXIT_FAILURE);
		}

		close(fd);
	}

	if (send_cmd(mgmt, MGMT_OP_SET_PRIVACY, index, sizeof(cp), &cp,
							setting_rsp) == 0) {
		error("Unable to send Set Privacy command");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void class_rsp(uint16_t op, uint16_t id, uint8_t status, uint16_t len,
							const void *param)
{
	const struct mgmt_ev_class_of_dev_changed *rp = param;

	if (len == 0 && status != 0) {
		error("%s failed, status 0x%02x (%s)",
				mgmt_opstr(op), status, mgmt_errstr(status));
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	if (len != sizeof(*rp)) {
		error("Unexpected %s len %u", mgmt_opstr(op), len);
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	print("%s succeeded. Class 0x%02x%02x%02x", mgmt_opstr(op),
		rp->dev_class[2], rp->dev_class[1], rp->dev_class[0]);

	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static void cmd_class(int argc, char **argv)
{
	uint8_t class[2];
	uint16_t index;

	class[0] = atoi(argv[1]);
	class[1] = atoi(argv[2]);

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	if (send_cmd(mgmt, MGMT_OP_SET_DEV_CLASS, index, sizeof(class), class,
							class_rsp) == 0) {
		error("Unable to send set_dev_class cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void disconnect_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_rp_disconnect *rp = param;
	char addr[18];

	if (len == 0 && status != 0) {
		error("Disconnect failed with status 0x%02x (%s)",
						status, mgmt_errstr(status));
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	if (len != sizeof(*rp)) {
		error("Invalid disconnect response length (%u)", len);
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	ba2str(&rp->addr.bdaddr, addr);

	if (status == 0)
		print("%s disconnected", addr);
	else
		error("Disconnecting %s failed with status 0x%02x (%s)",
				addr, status, mgmt_errstr(status));

	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static struct option disconnect_options[] = {
	{ "help",	0, 0, 'h' },
	{ "type",	1, 0, 't' },
	{ 0, 0, 0, 0 }
};

static void cmd_disconnect(int argc, char **argv)
{
	struct mgmt_cp_disconnect cp;
	uint8_t type = BDADDR_BREDR;
	int opt;
	uint16_t index;

	while ((opt = getopt_long(argc, argv, "+t:h", disconnect_options,
								NULL)) != -1) {
		switch (opt) {
		case 't':
			type = strtol(optarg, NULL, 0);
			break;
		case 'h':
			bt_shell_usage();
			optind = 0;
			return bt_shell_noninteractive_quit(EXIT_SUCCESS);
		default:
			bt_shell_usage();
			optind = 0;
			return bt_shell_noninteractive_quit(EXIT_FAILURE);
		}
	}

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

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	memset(&cp, 0, sizeof(cp));
	str2ba(argv[0], &cp.addr.bdaddr);
	cp.addr.type = type;

	if (mgmt_send(mgmt, MGMT_OP_DISCONNECT, index, sizeof(cp), &cp,
					disconnect_rsp, NULL, NULL) == 0) {
		error("Unable to send disconnect cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void con_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_rp_get_connections *rp = param;
	uint16_t count, i;

	if (len < sizeof(*rp)) {
		error("Too small (%u bytes) get_connections rsp", len);
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	count = get_le16(&rp->conn_count);
	if (len != sizeof(*rp) + count * sizeof(struct mgmt_addr_info)) {
		error("Invalid get_connections length (count=%u, len=%u)",
								count, len);
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	for (i = 0; i < count; i++) {
		char addr[18];

		ba2str(&rp->addr[i].bdaddr, addr);

		print("%s type %s", addr, typestr(rp->addr[i].type));
	}

	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static void cmd_con(int argc, char **argv)
{
	uint16_t index;

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	if (mgmt_send(mgmt, MGMT_OP_GET_CONNECTIONS, index, 0, NULL,
						con_rsp, NULL, NULL) == 0) {
		error("Unable to send get_connections cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void find_service_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	if (status != 0) {
		error("Start Service Discovery failed: status 0x%02x (%s)",
						status, mgmt_errstr(status));
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	print("Service discovery started");
	discovery = true;
}

static struct option find_service_options[] = {
	{ "help",	no_argument, 0, 'h' },
	{ "le-only",	no_argument, 0, 'l' },
	{ "bredr-only",	no_argument, 0, 'b' },
	{ "uuid",	required_argument, 0, 'u' },
	{ "rssi",	required_argument, 0, 'r' },
	{ 0, 0, 0, 0 }
};

static void uuid_to_uuid128(uuid_t *uuid128, const uuid_t *uuid)
{
	if (uuid->type == SDP_UUID16)
		sdp_uuid16_to_uuid128(uuid128, uuid);
	else if (uuid->type == SDP_UUID32)
		sdp_uuid32_to_uuid128(uuid128, uuid);
	else
		memcpy(uuid128, uuid, sizeof(*uuid));
}

#define MAX_UUIDS 4

static void cmd_find_service(int argc, char **argv)
{
	struct mgmt_cp_start_service_discovery *cp;
	uint8_t buf[sizeof(*cp) + 16 * MAX_UUIDS];
	uuid_t uuid;
	uint128_t uint128;
	uuid_t uuid128;
	uint8_t type = SCAN_TYPE_DUAL;
	int8_t rssi;
	uint16_t count;
	int opt;
	uint16_t index;

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	rssi = 127;
	count = 0;

	while ((opt = getopt_long(argc, argv, "+lbu:r:h",
					find_service_options, NULL)) != -1) {
		switch (opt) {
		case 'l':
			type &= ~SCAN_TYPE_BREDR;
			type |= SCAN_TYPE_LE;
			break;
		case 'b':
			type |= SCAN_TYPE_BREDR;
			type &= ~SCAN_TYPE_LE;
			break;
		case 'u':
			if (count == MAX_UUIDS) {
				print("Max %u UUIDs supported", MAX_UUIDS);
				optind = 0;
				return bt_shell_noninteractive_quit(EXIT_FAILURE);
			}

			if (bt_string2uuid(&uuid, optarg) < 0) {
				print("Invalid UUID: %s", optarg);
				optind = 0;
				return bt_shell_noninteractive_quit(EXIT_FAILURE);
			}
			cp = (void *) buf;
			uuid_to_uuid128(&uuid128, &uuid);
			ntoh128((uint128_t *) uuid128.value.uuid128.data,
				&uint128);
			htob128(&uint128, (uint128_t *) cp->uuids[count++]);
			break;
		case 'r':
			rssi = atoi(optarg);
			break;
		case 'h':
			bt_shell_usage();
			optind = 0;
			return bt_shell_noninteractive_quit(EXIT_SUCCESS);
		default:
			bt_shell_usage();
			optind = 0;
			return bt_shell_noninteractive_quit(EXIT_FAILURE);
		}
	}

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

	cp = (void *) buf;
	cp->type = type;
	cp->rssi = rssi;
	cp->uuid_count = cpu_to_le16(count);

	if (mgmt_send(mgmt, MGMT_OP_START_SERVICE_DISCOVERY, index,
				sizeof(*cp) + count * 16, cp,
				find_service_rsp, NULL, NULL) == 0) {
		error("Unable to send start_service_discovery cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void find_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	if (status != 0) {
		error("Unable to start discovery. status 0x%02x (%s)",
						status, mgmt_errstr(status));
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	print("Discovery started");
	discovery = true;
}

static struct option find_options[] = {
	{ "help",	0, 0, 'h' },
	{ "le-only",	1, 0, 'l' },
	{ "bredr-only",	1, 0, 'b' },
	{ "limited",	1, 0, 'L' },
	{ 0, 0, 0, 0 }
};

static void cmd_find(int argc, char **argv)
{
	struct mgmt_cp_start_discovery cp;
	uint8_t op = MGMT_OP_START_DISCOVERY;
	uint8_t type = SCAN_TYPE_DUAL;
	int opt;
	uint16_t index;

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	while ((opt = getopt_long(argc, argv, "+lbLh", find_options,
								NULL)) != -1) {
		switch (opt) {
		case 'l':
			type &= ~SCAN_TYPE_BREDR;
			type |= SCAN_TYPE_LE;
			break;
		case 'b':
			type |= SCAN_TYPE_BREDR;
			type &= ~SCAN_TYPE_LE;
			break;
		case 'L':
			op = MGMT_OP_START_LIMITED_DISCOVERY;
			break;
		case 'h':
			bt_shell_usage();
			optind = 0;
			return bt_shell_noninteractive_quit(EXIT_SUCCESS);
		default:
			bt_shell_usage();
			optind = 0;
			return bt_shell_noninteractive_quit(EXIT_FAILURE);
		}
	}

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

	memset(&cp, 0, sizeof(cp));
	cp.type = type;

	if (mgmt_send(mgmt, op, index, sizeof(cp), &cp, find_rsp,
							NULL, NULL) == 0) {
		error("Unable to send start_discovery cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void stop_find_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	if (status != 0) {
		error("Stop Discovery failed: status 0x%02x (%s)",
						status, mgmt_errstr(status));
		return bt_shell_noninteractive_quit(EXIT_SUCCESS);
	}

	print("Discovery stopped");
	discovery = false;

	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static struct option stop_find_options[] = {
	{ "help",	0, 0, 'h' },
	{ "le-only",	1, 0, 'l' },
	{ "bredr-only",	1, 0, 'b' },
	{ 0, 0, 0, 0 }
};

static void cmd_stop_find(int argc, char **argv)
{
	struct mgmt_cp_stop_discovery cp;
	uint8_t type = SCAN_TYPE_DUAL;
	int opt;
	uint16_t index;

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	while ((opt = getopt_long(argc, argv, "+lbh", stop_find_options,
								NULL)) != -1) {
		switch (opt) {
		case 'l':
			type &= ~SCAN_TYPE_BREDR;
			type |= SCAN_TYPE_LE;
			break;
		case 'b':
			type |= SCAN_TYPE_BREDR;
			type &= ~SCAN_TYPE_LE;
			break;
		case 'h':
		default:
			bt_shell_usage();
			optind = 0;
			return bt_shell_noninteractive_quit(EXIT_SUCCESS);
		}
	}

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

	memset(&cp, 0, sizeof(cp));
	cp.type = type;

	if (mgmt_send(mgmt, MGMT_OP_STOP_DISCOVERY, index, sizeof(cp), &cp,
					     stop_find_rsp, NULL, NULL) == 0) {
		error("Unable to send stop_discovery cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void name_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	if (status != 0)
		error("Unable to set local name with status 0x%02x (%s)",
						status, mgmt_errstr(status));

	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static void cmd_name(int argc, char **argv)
{
	struct mgmt_cp_set_local_name cp;
	uint16_t index;

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	memset(&cp, 0, sizeof(cp));
	strncpy((char *) cp.name, argv[1], HCI_MAX_NAME_LENGTH);
	if (argc > 2)
		strncpy((char *) cp.short_name, argv[2],
					MGMT_MAX_SHORT_NAME_LENGTH - 1);

	if (mgmt_send(mgmt, MGMT_OP_SET_LOCAL_NAME, index, sizeof(cp), &cp,
						name_rsp, NULL, NULL) == 0) {
		error("Unable to send set_name cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void pair_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_rp_pair_device *rp = param;
	char addr[18];

	if (len == 0 && status != 0) {
		error("Pairing failed with status 0x%02x (%s)",
						status, mgmt_errstr(status));
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	if (len != sizeof(*rp)) {
		error("Unexpected pair_rsp len %u", len);
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	ba2str(&rp->addr.bdaddr, addr);

	if (status)
		error("Pairing with %s (%s) failed. status 0x%02x (%s)",
			addr, typestr(rp->addr.type), status,
			mgmt_errstr(status));
	else
		print("Paired with %s (%s)", addr, typestr(rp->addr.type));

	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static struct option pair_options[] = {
	{ "help",	0, 0, 'h' },
	{ "capability",	1, 0, 'c' },
	{ "type",	1, 0, 't' },
	{ 0, 0, 0, 0 }
};

static void cmd_pair(int argc, char **argv)
{
	struct mgmt_cp_pair_device cp;
	uint8_t cap = 0x01;
	uint8_t type = BDADDR_BREDR;
	char addr[18];
	int opt;
	uint16_t index;

	while ((opt = getopt_long(argc, argv, "+c:t:h", pair_options,
								NULL)) != -1) {
		switch (opt) {
		case 'c':
			cap = strtol(optarg, NULL, 0);
			break;
		case 't':
			type = strtol(optarg, NULL, 0);
			break;
		case 'h':
			bt_shell_usage();
			optind = 0;
			return bt_shell_noninteractive_quit(EXIT_SUCCESS);
		default:
			bt_shell_usage();
			optind = 0;
			return bt_shell_noninteractive_quit(EXIT_FAILURE);
		}
	}

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

	if (argc < 1) {
		bt_shell_usage();
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	memset(&cp, 0, sizeof(cp));
	str2ba(argv[0], &cp.addr.bdaddr);
	cp.addr.type = type;
	cp.io_cap = cap;

	ba2str(&cp.addr.bdaddr, addr);
	print("Pairing with %s (%s)", addr, typestr(cp.addr.type));

	if (mgmt_send(mgmt, MGMT_OP_PAIR_DEVICE, index, sizeof(cp), &cp,
						pair_rsp, NULL, NULL) == 0) {
		error("Unable to send pair_device cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void cancel_pair_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_addr_info *rp = param;
	char addr[18];

	if (len == 0 && status != 0) {
		error("Cancel Pairing failed with 0x%02x (%s)",
						status, mgmt_errstr(status));
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	if (len != sizeof(*rp)) {
		error("Unexpected cancel_pair_rsp len %u", len);
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	ba2str(&rp->bdaddr, addr);

	if (status)
		error("Cancel Pairing with %s (%s) failed. 0x%02x (%s)",
			addr, typestr(rp->type), status,
			mgmt_errstr(status));
	else
		print("Pairing Cancelled with %s", addr);

	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static struct option cancel_pair_options[] = {
	{ "help",	0, 0, 'h' },
	{ "type",	1, 0, 't' },
	{ 0, 0, 0, 0 }
};

static void cmd_cancel_pair(int argc, char **argv)
{
	struct mgmt_addr_info cp;
	uint8_t type = BDADDR_BREDR;
	int opt;
	uint16_t index;

	while ((opt = getopt_long(argc, argv, "+t:h", cancel_pair_options,
								NULL)) != -1) {
		switch (opt) {
		case 't':
			type = strtol(optarg, NULL, 0);
			break;
		case 'h':
			bt_shell_usage();
			optind = 0;
			return bt_shell_noninteractive_quit(EXIT_SUCCESS);
		default:
			bt_shell_usage();
			optind = 0;
			return bt_shell_noninteractive_quit(EXIT_FAILURE);
		}
	}

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

	if (argc < 1) {
		bt_shell_usage();
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	memset(&cp, 0, sizeof(cp));
	str2ba(argv[0], &cp.bdaddr);
	cp.type = type;

	if (mgmt_reply(mgmt, MGMT_OP_CANCEL_PAIR_DEVICE, index, sizeof(cp), &cp,
					cancel_pair_rsp, NULL, NULL) == 0) {
		error("Unable to send cancel_pair_device cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void unpair_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_rp_unpair_device *rp = param;
	char addr[18];

	if (len == 0 && status != 0) {
		error("Unpair device failed. status 0x%02x (%s)",
						status, mgmt_errstr(status));
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	if (len != sizeof(*rp)) {
		error("Unexpected unpair_device_rsp len %u", len);
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	ba2str(&rp->addr.bdaddr, addr);

	if (status)
		error("Unpairing %s failed. status 0x%02x (%s)",
				addr, status, mgmt_errstr(status));
	else
		print("%s unpaired", addr);

	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static struct option unpair_options[] = {
	{ "help",	0, 0, 'h' },
	{ "type",	1, 0, 't' },
	{ 0, 0, 0, 0 }
};

static void cmd_unpair(int argc, char **argv)
{
	struct mgmt_cp_unpair_device cp;
	uint8_t type = BDADDR_BREDR;
	int opt;
	uint16_t index = mgmt_index;

	while ((opt = getopt_long(argc, argv, "+t:h", unpair_options,
								NULL)) != -1) {
		switch (opt) {
		case 't':
			type = strtol(optarg, NULL, 0);
			break;
		case 'h':
			bt_shell_usage();
			optind = 0;
			return bt_shell_noninteractive_quit(EXIT_SUCCESS);
		default:
			bt_shell_usage();
			optind = 0;
			return bt_shell_noninteractive_quit(EXIT_FAILURE);
		}
	}

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

	if (argc < 1) {
		bt_shell_usage();
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	memset(&cp, 0, sizeof(cp));
	str2ba(argv[0], &cp.addr.bdaddr);
	cp.addr.type = type;
	cp.disconnect = 1;

	if (mgmt_send(mgmt, MGMT_OP_UNPAIR_DEVICE, index, sizeof(cp), &cp,
						unpair_rsp, NULL, NULL) == 0) {
		error("Unable to send unpair_device cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void keys_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	if (status != 0)
		error("Load keys failed with status 0x%02x (%s)",
						status, mgmt_errstr(status));
	else
		print("Keys successfully loaded");

	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static void cmd_keys(int argc, char **argv)
{
	struct mgmt_cp_load_link_keys cp;
	uint16_t index;

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

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

	if (mgmt_send(mgmt, MGMT_OP_LOAD_LINK_KEYS, index, sizeof(cp), &cp,
						keys_rsp, NULL, NULL) == 0) {
		error("Unable to send load_keys cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void ltks_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	if (status != 0)
		error("Load keys failed with status 0x%02x (%s)",
						status, mgmt_errstr(status));
	else
		print("Long term keys successfully loaded");

	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static void cmd_ltks(int argc, char **argv)
{
	struct mgmt_cp_load_long_term_keys cp;
	uint16_t index;

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

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

	if (mgmt_send(mgmt, MGMT_OP_LOAD_LONG_TERM_KEYS, index, sizeof(cp), &cp,
						ltks_rsp, NULL, NULL) == 0) {
		error("Unable to send load_ltks cmd");
		return bt_shell_noninteractive_quit(EXIT_SUCCESS);
	}
}

static void irks_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	if (status != 0)
		error("Load IRKs failed with status 0x%02x (%s)",
						status, mgmt_errstr(status));
	else
		print("Identity Resolving Keys successfully loaded");

	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static struct option irks_options[] = {
	{ "help",	0, 0, 'h' },
	{ "local",	1, 0, 'l' },
	{ "file",	1, 0, 'f' },
	{ 0, 0, 0, 0 }
};

#define MAX_IRKS 4

static void cmd_irks(int argc, char **argv)
{
	struct mgmt_cp_load_irks *cp;
	uint8_t buf[sizeof(*cp) + 23 * MAX_IRKS];
	uint16_t count, local_index;
	char path[PATH_MAX];
	int opt;
	uint16_t index;

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	cp = (void *) buf;
	count = 0;

	while ((opt = getopt_long(argc, argv, "+l:f:h",
					irks_options, NULL)) != -1) {
		switch (opt) {
		case 'l':
			if (count >= MAX_IRKS) {
				error("Number of IRKs exceeded");
				optind = 0;
				return bt_shell_noninteractive_quit(EXIT_FAILURE);
			}
			if (strlen(optarg) > 3 &&
					strncasecmp(optarg, "hci", 3) == 0)
				local_index = atoi(optarg + 3);
			else
				local_index = atoi(optarg);
			snprintf(path, sizeof(path),
				"/sys/kernel/debug/bluetooth/hci%u/identity",
				local_index);
			if (!load_identity(path, &cp->irks[count])) {
				error("Unable to load identity");
				optind = 0;
				return bt_shell_noninteractive_quit(EXIT_FAILURE);
			}
			count++;
			break;
		case 'f':
			if (count >= MAX_IRKS) {
				error("Number of IRKs exceeded");
				optind = 0;
				return bt_shell_noninteractive_quit(EXIT_FAILURE);
			}
			if (!load_identity(optarg, &cp->irks[count])) {
				error("Unable to load identities");
				optind = 0;
				return bt_shell_noninteractive_quit(EXIT_FAILURE);
			}
			count++;
			break;
		case 'h':
			bt_shell_usage();
			optind = 0;
			return bt_shell_noninteractive_quit(EXIT_SUCCESS);
		default:
			bt_shell_usage();
			optind = 0;
			return bt_shell_noninteractive_quit(EXIT_FAILURE);
		}
	}

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

	cp->irk_count = cpu_to_le16(count);

	if (mgmt_send(mgmt, MGMT_OP_LOAD_IRKS, index,
					sizeof(*cp) + count * 23, cp,
					irks_rsp, NULL, NULL) == 0) {
		error("Unable to send load_irks cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void block_rsp(uint16_t op, uint16_t id, uint8_t status, uint16_t len,
							const void *param)
{
	const struct mgmt_addr_info *rp = param;
	char addr[18];

	if (len == 0 && status != 0) {
		error("%s failed, status 0x%02x (%s)",
				mgmt_opstr(op), status, mgmt_errstr(status));
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	if (len != sizeof(*rp)) {
		error("Unexpected %s len %u", mgmt_opstr(op), len);
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	ba2str(&rp->bdaddr, addr);

	if (status)
		error("%s %s (%s) failed. status 0x%02x (%s)",
				mgmt_opstr(op), addr, typestr(rp->type),
				status, mgmt_errstr(status));
	else
		print("%s %s succeeded", mgmt_opstr(op), addr);

	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static struct option block_options[] = {
	{ "help",	0, 0, 'h' },
	{ "type",	1, 0, 't' },
	{ 0, 0, 0, 0 }
};

static void cmd_block(int argc, char **argv)
{
	struct mgmt_cp_block_device cp;
	uint8_t type = BDADDR_BREDR;
	int opt;
	uint16_t index;

	while ((opt = getopt_long(argc, argv, "+t:h", block_options,
							NULL)) != -1) {
		switch (opt) {
		case 't':
			type = strtol(optarg, NULL, 0);
			break;
		case 'h':
			bt_shell_usage();
			optind = 0;
			return bt_shell_noninteractive_quit(EXIT_SUCCESS);
		default:
			bt_shell_usage();
			optind = 0;
			return bt_shell_noninteractive_quit(EXIT_FAILURE);
		}
	}

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

	if (argc < 1) {
		bt_shell_usage();
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	memset(&cp, 0, sizeof(cp));
	str2ba(argv[0], &cp.addr.bdaddr);
	cp.addr.type = type;

	if (send_cmd(mgmt, MGMT_OP_BLOCK_DEVICE, index, sizeof(cp), &cp,
							block_rsp) == 0) {
		error("Unable to send block_device cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void cmd_unblock(int argc, char **argv)
{
	struct mgmt_cp_unblock_device cp;
	uint8_t type = BDADDR_BREDR;
	int opt;
	uint16_t index;

	while ((opt = getopt_long(argc, argv, "+t:h", block_options,
							NULL)) != -1) {
		switch (opt) {
		case 't':
			type = strtol(optarg, NULL, 0);
			break;
		case 'h':
			bt_shell_usage();
			optind = 0;
			return bt_shell_noninteractive_quit(EXIT_SUCCESS);
		default:
			bt_shell_usage();
			optind = 0;
			return bt_shell_noninteractive_quit(EXIT_FAILURE);
		}
	}

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

	if (argc < 1) {
		bt_shell_usage();
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	memset(&cp, 0, sizeof(cp));
	str2ba(argv[0], &cp.addr.bdaddr);
	cp.addr.type = type;

	if (send_cmd(mgmt, MGMT_OP_UNBLOCK_DEVICE, index, sizeof(cp), &cp,
							block_rsp) == 0) {
		error("Unable to send unblock_device cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void cmd_add_uuid(int argc, char **argv)
{
	struct mgmt_cp_add_uuid cp;
	uint128_t uint128;
	uuid_t uuid, uuid128;
	uint16_t index;

	if (argc < 3) {
		print("UUID and service hint needed");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	if (bt_string2uuid(&uuid, argv[1]) < 0) {
		print("Invalid UUID: %s", argv[1]);
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

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

	uuid_to_uuid128(&uuid128, &uuid);
	ntoh128((uint128_t *) uuid128.value.uuid128.data, &uint128);
	htob128(&uint128, (uint128_t *) cp.uuid);

	cp.svc_hint = atoi(argv[2]);

	if (send_cmd(mgmt, MGMT_OP_ADD_UUID, index, sizeof(cp), &cp,
							class_rsp) == 0) {
		error("Unable to send add_uuid cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void cmd_remove_uuid(int argc, char **argv)
{
	struct mgmt_cp_remove_uuid cp;
	uint128_t uint128;
	uuid_t uuid, uuid128;
	uint16_t index;

	if (argc < 2) {
		print("UUID needed");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	if (bt_string2uuid(&uuid, argv[1]) < 0) {
		print("Invalid UUID: %s", argv[1]);
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

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

	uuid_to_uuid128(&uuid128, &uuid);
	ntoh128((uint128_t *) uuid128.value.uuid128.data, &uint128);
	htob128(&uint128, (uint128_t *) cp.uuid);

	if (send_cmd(mgmt, MGMT_OP_REMOVE_UUID, index, sizeof(cp), &cp,
							class_rsp) == 0) {
		error("Unable to send remove_uuid cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void cmd_clr_uuids(int argc, char **argv)
{
	char *uuid_any = "00000000-0000-0000-0000-000000000000";
	char *rm_argv[] = { "rm-uuid", uuid_any, NULL };

	cmd_remove_uuid(2, rm_argv);
}

static void local_oob_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_rp_read_local_oob_data *rp = param;
	char str[33];

	if (status != 0) {
		error("Read Local OOB Data failed with status 0x%02x (%s)",
						status, mgmt_errstr(status));
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	if (len < sizeof(*rp)) {
		error("Too small (%u bytes) read_local_oob rsp", len);
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	bin2hex(rp->hash192, 16, str, sizeof(str));
	print("Hash C from P-192: %s", str);

	bin2hex(rp->rand192, 16, str, sizeof(str));
	print("Randomizer R with P-192: %s", str);

	if (len < sizeof(*rp))
		return bt_shell_noninteractive_quit(EXIT_SUCCESS);

	bin2hex(rp->hash256, 16, str, sizeof(str));
	print("Hash C from P-256: %s", str);

	bin2hex(rp->rand256, 16, str, sizeof(str));
	print("Randomizer R with P-256: %s", str);

	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static void cmd_local_oob(int argc, char **argv)
{
	uint16_t index;

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	if (mgmt_send(mgmt, MGMT_OP_READ_LOCAL_OOB_DATA, index, 0, NULL,
					local_oob_rsp, NULL, NULL) == 0) {
		error("Unable to send read_local_oob cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void remote_oob_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_addr_info *rp = param;
	char addr[18];

	if (status != 0) {
		error("Add Remote OOB Data failed: 0x%02x (%s)",
						status, mgmt_errstr(status));
		return;
	}

	if (len < sizeof(*rp)) {
		error("Too small (%u bytes) add_remote_oob rsp", len);
		return;
	}

	ba2str(&rp->bdaddr, addr);
	print("Remote OOB data added for %s (%u)", addr, rp->type);
}

static struct option remote_oob_opt[] = {
	{ "help",	0, 0, '?' },
	{ "type",	1, 0, 't' },
	{ 0, 0, 0, 0 }
};

static void cmd_remote_oob(int argc, char **argv)
{
	struct mgmt_cp_add_remote_oob_data cp;
	int opt;
	uint16_t index;

	memset(&cp, 0, sizeof(cp));
	cp.addr.type = BDADDR_BREDR;

	while ((opt = getopt_long(argc, argv, "+t:r:R:h:H:",
					remote_oob_opt, NULL)) != -1) {
		switch (opt) {
		case 't':
			cp.addr.type = strtol(optarg, NULL, 0);
			break;
		case 'r':
			hex2bin(optarg, cp.rand192, 16);
			break;
		case 'h':
			hex2bin(optarg, cp.hash192, 16);
			break;
		case 'R':
			hex2bin(optarg, cp.rand256, 16);
			break;
		case 'H':
			hex2bin(optarg, cp.hash256, 16);
			break;
		default:
			bt_shell_usage();
			optind = 0;
			return bt_shell_noninteractive_quit(EXIT_FAILURE);
		}
	}

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

	if (argc < 1) {
		bt_shell_usage();
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	str2ba(argv[0], &cp.addr.bdaddr);

	print("Adding OOB data for %s (%s)", argv[0], typestr(cp.addr.type));

	if (mgmt_send(mgmt, MGMT_OP_ADD_REMOTE_OOB_DATA, index,
				sizeof(cp), &cp, remote_oob_rsp,
				NULL, NULL) == 0) {
		error("Unable to send add_remote_oob cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void did_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	if (status != 0)
		error("Set Device ID failed with status 0x%02x (%s)",
						status, mgmt_errstr(status));
	else
		print("Device ID successfully set");

	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static void cmd_did(int argc, char **argv)
{
	struct mgmt_cp_set_device_id cp;
	uint16_t vendor, product, version , source;
	int result;
	uint16_t index;

	result = sscanf(argv[1], "bluetooth:%4hx:%4hx:%4hx", &vendor, &product,
								&version);
	if (result == 3) {
		source = 0x0001;
		goto done;
	}

	result = sscanf(argv[1], "usb:%4hx:%4hx:%4hx", &vendor, &product,
								&version);
	if (result == 3) {
		source = 0x0002;
		goto done;
	}

	return;
done:
	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	cp.source = htobs(source);
	cp.vendor = htobs(vendor);
	cp.product = htobs(product);
	cp.version = htobs(version);

	if (mgmt_send(mgmt, MGMT_OP_SET_DEVICE_ID, index, sizeof(cp), &cp,
						did_rsp, NULL, NULL) == 0) {
		error("Unable to send set_device_id cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void static_addr_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	if (status != 0)
		error("Set static address failed with status 0x%02x (%s)",
						status, mgmt_errstr(status));
	else
		print("Static address successfully set");

	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static void cmd_static_addr(int argc, char **argv)
{
	struct mgmt_cp_set_static_address cp;
	uint16_t index;

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	str2ba(argv[1], &cp.bdaddr);

	if (mgmt_send(mgmt, MGMT_OP_SET_STATIC_ADDRESS, index, sizeof(cp), &cp,
					static_addr_rsp, NULL, NULL) == 0) {
		error("Unable to send set_static_address cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void options_rsp(uint16_t op, uint16_t id, uint8_t status,
					uint16_t len, const void *param)
{
	const uint32_t *rp = param;

	if (status != 0) {
		error("%s for hci%u failed with status 0x%02x (%s)",
			mgmt_opstr(op), id, status, mgmt_errstr(status));
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	if (len < sizeof(*rp)) {
		error("Too small %s response (%u bytes)",
							mgmt_opstr(op), len);
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	print("hci%u %s complete, options: %s", id, mgmt_opstr(op),
						options2str(get_le32(rp)));

	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static void cmd_public_addr(int argc, char **argv)
{
	struct mgmt_cp_set_public_address cp;
	uint16_t index;

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	str2ba(argv[1], &cp.bdaddr);

	if (send_cmd(mgmt, MGMT_OP_SET_PUBLIC_ADDRESS, index, sizeof(cp), &cp,
							options_rsp) == 0) {
		error("Unable to send Set Public Address cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void cmd_ext_config(int argc, char **argv)
{
	struct mgmt_cp_set_external_config cp;
	uint16_t index;

	if (parse_setting(argc, argv, &cp.config) == false)
		return bt_shell_noninteractive_quit(EXIT_FAILURE);

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	if (send_cmd(mgmt, MGMT_OP_SET_EXTERNAL_CONFIG, index, sizeof(cp), &cp,
							options_rsp) == 0) {
		error("Unable to send Set External Config cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void cmd_debug_keys(int argc, char **argv)
{
	cmd_setting(MGMT_OP_SET_DEBUG_KEYS, argc, argv);
}

static void conn_info_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_rp_get_conn_info *rp = param;	char addr[18];

	if (len == 0 && status != 0) {
		error("Get Conn Info failed, status 0x%02x (%s)",
						status, mgmt_errstr(status));
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	if (len < sizeof(*rp)) {
		error("Unexpected Get Conn Info len %u", len);
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	ba2str(&rp->addr.bdaddr, addr);

	if (status) {
		error("Get Conn Info for %s (%s) failed. status 0x%02x (%s)",
						addr, typestr(rp->addr.type),
						status, mgmt_errstr(status));
	} else {
		print("Connection Information for %s (%s)",
						addr, typestr(rp->addr.type));
		print("\tRSSI %d\tTX power %d\tmaximum TX power %d",
				rp->rssi, rp->tx_power, rp->max_tx_power);
	}

	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static struct option conn_info_options[] = {
	{ "help",       0, 0, 'h' },
	{ "type",       1, 0, 't' },
	{ 0, 0, 0, 0 }
};

static void cmd_conn_info(int argc, char **argv)
{
	struct mgmt_cp_get_conn_info cp;
	uint8_t type = BDADDR_BREDR;
	int opt;
	uint16_t index;

	while ((opt = getopt_long(argc, argv, "+t:h", conn_info_options,
								NULL)) != -1) {
		switch (opt) {
		case 't':
			type = strtol(optarg, NULL, 0);
			break;
		case 'h':
			bt_shell_usage();
			optind = 0;
			return bt_shell_noninteractive_quit(EXIT_SUCCESS);
		default:
			bt_shell_usage();
			optind = 0;
			return bt_shell_noninteractive_quit(EXIT_FAILURE);
		}
	}

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

	if (argc < 1) {
		bt_shell_usage();
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	memset(&cp, 0, sizeof(cp));
	str2ba(argv[0], &cp.addr.bdaddr);
	cp.addr.type = type;

	if (mgmt_send(mgmt, MGMT_OP_GET_CONN_INFO, index, sizeof(cp), &cp,
					conn_info_rsp, NULL, NULL) == 0) {
		error("Unable to send get_conn_info cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void io_cap_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	if (status != 0)
		error("Could not set IO Capability with status 0x%02x (%s)",
						status, mgmt_errstr(status));
	else
		print("IO Capabilities successfully set");

	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static void cmd_io_cap(int argc, char **argv)
{
	struct mgmt_cp_set_io_capability cp;
	uint8_t cap;
	uint16_t index;

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	cap = strtol(argv[1], NULL, 0);
	memset(&cp, 0, sizeof(cp));
	cp.io_capability = cap;

	if (mgmt_send(mgmt, MGMT_OP_SET_IO_CAPABILITY, index, sizeof(cp), &cp,
					io_cap_rsp, NULL, NULL) == 0) {
		error("Unable to send set-io-cap cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void scan_params_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	if (status != 0)
		error("Set scan parameters failed with status 0x%02x (%s)",
						status, mgmt_errstr(status));
	else
		print("Scan parameters successfully set");

	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static void cmd_scan_params(int argc, char **argv)
{
	struct mgmt_cp_set_scan_params cp;
	uint16_t index;

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	cp.interval = strtol(argv[1], NULL, 0);
	cp.window = strtol(argv[2], NULL, 0);

	if (mgmt_send(mgmt, MGMT_OP_SET_SCAN_PARAMS, index, sizeof(cp), &cp,
					scan_params_rsp, NULL, NULL) == 0) {
		error("Unable to send set_scan_params cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void clock_info_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_rp_get_clock_info *rp = param;

	if (len < sizeof(*rp)) {
		error("Unexpected Get Clock Info len %u", len);
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	if (status) {
		error("Get Clock Info failed with status 0x%02x (%s)",
						status, mgmt_errstr(status));
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	print("Local Clock:   %u", le32_to_cpu(rp->local_clock));
	print("Piconet Clock: %u", le32_to_cpu(rp->piconet_clock));
	print("Accurary:      %u", le16_to_cpu(rp->accuracy));

	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static void cmd_clock_info(int argc, char **argv)
{
	struct mgmt_cp_get_clock_info cp;
	uint16_t index;

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

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

	if (argc > 1)
		str2ba(argv[1], &cp.addr.bdaddr);

	if (mgmt_send(mgmt, MGMT_OP_GET_CLOCK_INFO, index, sizeof(cp), &cp,
					clock_info_rsp, NULL, NULL) == 0) {
		error("Unable to send get_clock_info cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void add_device_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	if (status != 0)
		error("Add device failed with status 0x%02x (%s)",
						status, mgmt_errstr(status));
	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static struct option add_device_options[] = {
	{ "help",	0, 0, 'h' },
	{ "action",	1, 0, 'a' },
	{ "type",	1, 0, 't' },
	{ 0, 0, 0, 0 }
};

static void cmd_add_device(int argc, char **argv)
{
	struct mgmt_cp_add_device cp;
	uint8_t action = 0x00;
	uint8_t type = BDADDR_BREDR;
	char addr[18];
	int opt;
	uint16_t index;

	while ((opt = getopt_long(argc, argv, "+a:t:h", add_device_options,
								NULL)) != -1) {
		switch (opt) {
		case 'a':
			action = strtol(optarg, NULL, 0);
			break;
		case 't':
			type = strtol(optarg, NULL, 0);
			break;
		case 'h':
			bt_shell_usage();
			optind = 0;
			return bt_shell_noninteractive_quit(EXIT_SUCCESS);
		default:
			bt_shell_usage();
			optind = 0;
			return bt_shell_noninteractive_quit(EXIT_FAILURE);
		}
	}

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

	if (argc < 1) {
		bt_shell_usage();
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	memset(&cp, 0, sizeof(cp));
	str2ba(argv[0], &cp.addr.bdaddr);
	cp.addr.type = type;
	cp.action = action;

	ba2str(&cp.addr.bdaddr, addr);
	print("Adding device with %s (%s)", addr, typestr(cp.addr.type));

	if (mgmt_send(mgmt, MGMT_OP_ADD_DEVICE, index, sizeof(cp), &cp,
					add_device_rsp, NULL, NULL) == 0) {
		error("Unable to send add device command");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void remove_device_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	if (status != 0)
		error("Remove device failed with status 0x%02x (%s)",
						status, mgmt_errstr(status));
	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static struct option del_device_options[] = {
	{ "help",	0, 0, 'h' },
	{ "type",	1, 0, 't' },
	{ 0, 0, 0, 0 }
};

static void cmd_del_device(int argc, char **argv)
{
	struct mgmt_cp_remove_device cp;
	uint8_t type = BDADDR_BREDR;
	char addr[18];
	int opt;
	uint16_t index;

	while ((opt = getopt_long(argc, argv, "+t:h", del_device_options,
								NULL)) != -1) {
		switch (opt) {
		case 't':
			type = strtol(optarg, NULL, 0);
			break;
		case 'h':
			bt_shell_usage();
			optind = 0;
			return bt_shell_noninteractive_quit(EXIT_SUCCESS);
		default:
			bt_shell_usage();
			optind = 0;
			return bt_shell_noninteractive_quit(EXIT_FAILURE);
		}
	}

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

	if (argc < 1) {
		bt_shell_usage();
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}


	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	memset(&cp, 0, sizeof(cp));
	str2ba(argv[0], &cp.addr.bdaddr);
	cp.addr.type = type;

	ba2str(&cp.addr.bdaddr, addr);
	print("Removing device with %s (%s)", addr, typestr(cp.addr.type));

	if (mgmt_send(mgmt, MGMT_OP_REMOVE_DEVICE, index, sizeof(cp), &cp,
					remove_device_rsp, NULL, NULL) == 0) {
		error("Unable to send remove device command");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void cmd_clr_devices(int argc, char **argv)
{
	char *bdaddr_any = "00:00:00:00:00:00";
	char *rm_argv[] = { "del-device", bdaddr_any, NULL };

	cmd_del_device(2, rm_argv);
}

static void local_oob_ext_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_rp_read_local_oob_ext_data *rp = param;
	uint16_t eir_len;

	if (status != 0) {
		error("Read Local OOB Ext Data failed with status 0x%02x (%s)",
						status, mgmt_errstr(status));
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	if (len < sizeof(*rp)) {
		error("Too small (%u bytes) read_local_oob_ext rsp", len);
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	eir_len = le16_to_cpu(rp->eir_len);
	if (len != sizeof(*rp) + eir_len) {
		error("local_oob_ext: expected %zu bytes, got %u bytes",
						sizeof(*rp) + eir_len, len);
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	print_eir(rp->eir, eir_len);

	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static void cmd_bredr_oob(int argc, char **argv)
{
	struct mgmt_cp_read_local_oob_ext_data cp;
	uint16_t index;

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	cp.type = SCAN_TYPE_BREDR;

	if (!mgmt_send(mgmt, MGMT_OP_READ_LOCAL_OOB_EXT_DATA,
					index, sizeof(cp), &cp,
					local_oob_ext_rsp, NULL, NULL)) {
		error("Unable to send read_local_oob_ext cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void cmd_le_oob(int argc, char **argv)
{
	struct mgmt_cp_read_local_oob_ext_data cp;
	uint16_t index;

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	cp.type = SCAN_TYPE_LE;

	if (!mgmt_send(mgmt, MGMT_OP_READ_LOCAL_OOB_EXT_DATA,
					index, sizeof(cp), &cp,
					local_oob_ext_rsp, NULL, NULL)) {
		error("Unable to send read_local_oob_ext cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static const char *adv_flags_str[] = {
				"connectable",
				"general-discoverable",
				"limited-discoverable",
				"managed-flags",
				"tx-power",
				"scan-rsp-appearance",
				"scan-rsp-local-name",
};

static const char *adv_flags2str(uint32_t flags)
{
	static char str[256];
	unsigned i;
	int off;

	off = 0;
	str[0] = '\0';

	for (i = 0; i < NELEM(adv_flags_str); i++) {
		if ((flags & (1 << i)) != 0)
			off += snprintf(str + off, sizeof(str) - off, "%s ",
							adv_flags_str[i]);
	}

	return str;
}

static void adv_features_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_rp_read_adv_features *rp = param;
	uint32_t supported_flags;

	if (status != 0) {
		error("Reading adv features failed with status 0x%02x (%s)",
						status, mgmt_errstr(status));
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	if (len < sizeof(*rp)) {
		error("Too small adv features reply (%u bytes)", len);
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	if (len < sizeof(*rp) + rp->num_instances * sizeof(uint8_t)) {
		error("Instances count (%u) doesn't match reply length (%u)",
							rp->num_instances, len);
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	supported_flags = le32_to_cpu(rp->supported_flags);
	print("Supported flags: %s", adv_flags2str(supported_flags));
	print("Max advertising data len: %u", rp->max_adv_data_len);
	print("Max scan response data len: %u", rp->max_scan_rsp_len);
	print("Max instances: %u", rp->max_instances);

	print("Instances list with %u item%s", rp->num_instances,
					rp->num_instances != 1 ? "s" : "");

	return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static void cmd_advinfo(int argc, char **argv)
{
	uint16_t index;

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	if (!mgmt_send(mgmt, MGMT_OP_READ_ADV_FEATURES, index, 0, NULL,
					adv_features_rsp, NULL, NULL)) {
		error("Unable to send advertising features command");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void adv_size_info_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	const struct mgmt_rp_get_adv_size_info *rp = param;
	uint32_t flags;

	if (status != 0) {
		error("Reading adv size info failed with status 0x%02x (%s)",
						status, mgmt_errstr(status));
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	if (len < sizeof(*rp)) {
		error("Too small adv size info reply (%u bytes)", len);
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	flags = le32_to_cpu(rp->flags);
	print("Instance: %u", rp->instance);
	print("Flags: %s", adv_flags2str(flags));
	print("Max advertising data len: %u", rp->max_adv_data_len);
	print("Max scan response data len: %u", rp->max_scan_rsp_len);

	return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static void advsize_usage(void)
{
	bt_shell_usage();
	print("Options:\n"
		"\t -c, --connectable         \"connectable\" flag\n"
		"\t -g, --general-discov      \"general-discoverable\" flag\n"
		"\t -l, --limited-discov      \"limited-discoverable\" flag\n"
		"\t -m, --managed-flags       \"managed-flags\" flag\n"
		"\t -p, --tx-power            \"tx-power\" flag\n"
		"\t -a, --appearance          \"appearance\" flag\n"
		"\t -n, --local-name          \"local-name\" flag");
}

static struct option advsize_options[] = {
	{ "help",		0, 0, 'h' },
	{ "connectable",	0, 0, 'c' },
	{ "general-discov",	0, 0, 'g' },
	{ "limited-discov",	0, 0, 'l' },
	{ "managed-flags",	0, 0, 'm' },
	{ "tx-power",		0, 0, 'p' },
	{ "appearance",		0, 0, 'a' },
	{ "local-name",		0, 0, 'n' },
	{ 0, 0, 0, 0}
};

static void cmd_advsize(int argc, char **argv)
{
	struct mgmt_cp_get_adv_size_info cp;
	uint8_t instance;
	uint32_t flags = 0;
	int opt;
	uint16_t index;

	while ((opt = getopt_long(argc, argv, "+cglmphna",
						advsize_options, NULL)) != -1) {
		switch (opt) {
		case 'c':
			flags |= MGMT_ADV_FLAG_CONNECTABLE;
			break;
		case 'g':
			flags |= MGMT_ADV_FLAG_DISCOV;
			break;
		case 'l':
			flags |= MGMT_ADV_FLAG_LIMITED_DISCOV;
			break;
		case 'm':
			flags |= MGMT_ADV_FLAG_MANAGED_FLAGS;
			break;
		case 'p':
			flags |= MGMT_ADV_FLAG_TX_POWER;
			break;
		case 'a':
			flags |= MGMT_ADV_FLAG_APPEARANCE;
			break;
		case 'n':
			flags |= MGMT_ADV_FLAG_LOCAL_NAME;
			break;
		default:
			advsize_usage();
			optind = 0;
			return bt_shell_noninteractive_quit(EXIT_FAILURE);
		}
	}

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

	if (argc != 1) {
		advsize_usage();
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	instance = strtol(argv[0], NULL, 0);

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

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

	cp.instance = instance;
	cp.flags = cpu_to_le32(flags);

	if (!mgmt_send(mgmt, MGMT_OP_GET_ADV_SIZE_INFO, index, sizeof(cp), &cp,
					adv_size_info_rsp, NULL, NULL)) {
		error("Unable to send advertising size info command");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void add_adv_rsp(uint8_t status, uint16_t len, const void *param,
								void *user_data)
{
	const struct mgmt_rp_add_advertising *rp = param;

	if (status != 0) {
		error("Add Advertising failed with status 0x%02x (%s)",
						status, mgmt_errstr(status));
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	if (len != sizeof(*rp)) {
		error("Invalid Add Advertising response length (%u)", len);
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	print("Instance added: %u", rp->instance);

	return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static void add_adv_usage(void)
{
	bt_shell_usage();
	print("Options:\n"
		"\t -u, --uuid <uuid>         Service UUID\n"
		"\t -d, --adv-data <data>     Advertising Data bytes\n"
		"\t -s, --scan-rsp <data>     Scan Response Data bytes\n"
		"\t -t, --timeout <timeout>   Timeout in seconds\n"
		"\t -D, --duration <duration> Duration in seconds\n"
		"\t -c, --connectable         \"connectable\" flag\n"
		"\t -g, --general-discov      \"general-discoverable\" flag\n"
		"\t -l, --limited-discov      \"limited-discoverable\" flag\n"
		"\t -n, --scan-rsp-local-name \"local-name\" flag\n"
		"\t -a, --scan-rsp-appearance \"appearance\" flag\n"
		"\t -m, --managed-flags       \"managed-flags\" flag\n"
		"\t -p, --tx-power            \"tx-power\" flag\n"
		"e.g.:\n"
		"\tadd-adv -u 180d -u 180f -d 080954657374204C45 1");
}

static struct option add_adv_options[] = {
	{ "help",		0, 0, 'h' },
	{ "uuid",		1, 0, 'u' },
	{ "adv-data",		1, 0, 'd' },
	{ "scan-rsp",		1, 0, 's' },
	{ "timeout",		1, 0, 't' },
	{ "duration",		1, 0, 'D' },
	{ "connectable",	0, 0, 'c' },
	{ "general-discov",	0, 0, 'g' },
	{ "limited-discov",	0, 0, 'l' },
	{ "managed-flags",	0, 0, 'm' },
	{ "tx-power",		0, 0, 'p' },
	{ 0, 0, 0, 0}
};

static bool parse_bytes(char *optarg, uint8_t **bytes, size_t *len)
{
	unsigned i;

	if (!optarg) {
		add_adv_usage();
		return false;
	}

	*len = strlen(optarg);

	if (*len % 2) {
		error("Malformed data");
		return false;
	}

	*len /= 2;
	if (*len > UINT8_MAX) {
		error("Data too long");
		return false;
	}

	*bytes = malloc(*len);
	if (!*bytes) {
		error("Failed to allocate memory");
		return false;
	}

	for (i = 0; i < *len; i++) {
		if (sscanf(optarg + (i * 2), "%2hhx", *bytes + i) != 1) {
			error("Invalid data");
			free(*bytes);
			*bytes = NULL;
			return false;
		}
	}

	return true;
}

#define MAX_AD_UUID_BYTES 32

static void cmd_add_adv(int argc, char **argv)
{
	struct mgmt_cp_add_advertising *cp = NULL;
	int opt;
	uint8_t *adv_data = NULL, *scan_rsp = NULL;
	size_t adv_len = 0, scan_rsp_len = 0;
	size_t cp_len;
	uint8_t uuids[MAX_AD_UUID_BYTES];
	size_t uuid_bytes = 0;
	uint8_t uuid_type = 0;
	uint16_t timeout = 0, duration = 0;
	uint8_t instance;
	uuid_t uuid;
	bool success = false;
	bool quit = true;
	uint32_t flags = 0;
	uint16_t index;

	while ((opt = getopt_long(argc, argv, "+u:d:s:t:D:cglmphna",
						add_adv_options, NULL)) != -1) {
		switch (opt) {
		case 'u':
			if (bt_string2uuid(&uuid, optarg) < 0) {
				print("Invalid UUID: %s", optarg);
				goto done;
			}

			if (uuid_type && uuid_type != uuid.type) {
				print("UUID types must be consistent");
				goto done;
			}

			if (uuid.type == SDP_UUID16) {
				if (uuid_bytes + 2 >= MAX_AD_UUID_BYTES) {
					print("Too many UUIDs");
					goto done;
				}

				put_le16(uuid.value.uuid16, uuids + uuid_bytes);
				uuid_bytes += 2;
			} else if (uuid.type == SDP_UUID128) {
				if (uuid_bytes + 16 >= MAX_AD_UUID_BYTES) {
					print("Too many UUIDs");
					goto done;
				}

				bswap_128(uuid.value.uuid128.data,
							uuids + uuid_bytes);
				uuid_bytes += 16;
			} else {
				printf("Unsupported UUID type");
				goto done;
			}

			if (!uuid_type)
				uuid_type = uuid.type;

			break;
		case 'd':
			if (adv_len) {
				print("Only one adv-data option allowed");
				goto done;
			}

			if (!parse_bytes(optarg, &adv_data, &adv_len))
				goto done;
			break;
		case 's':
			if (scan_rsp_len) {
				print("Only one scan-rsp option allowed");
				goto done;
			}

			if (!parse_bytes(optarg, &scan_rsp, &scan_rsp_len))
				goto done;
			break;
		case 't':
			timeout = strtol(optarg, NULL, 0);
			break;
		case 'D':
			duration = strtol(optarg, NULL, 0);
			break;
		case 'c':
			flags |= MGMT_ADV_FLAG_CONNECTABLE;
			break;
		case 'g':
			flags |= MGMT_ADV_FLAG_DISCOV;
			break;
		case 'l':
			flags |= MGMT_ADV_FLAG_LIMITED_DISCOV;
			break;
		case 'm':
			flags |= MGMT_ADV_FLAG_MANAGED_FLAGS;
			break;
		case 'p':
			flags |= MGMT_ADV_FLAG_TX_POWER;
			break;
		case 'n':
			flags |= MGMT_ADV_FLAG_LOCAL_NAME;
			break;
		case 'a':
			flags |= MGMT_ADV_FLAG_APPEARANCE;
			break;
		case 'h':
			success = true;
			/* fall through */
		default:
			add_adv_usage();
			optind = 0;
			goto done;
		}
	}

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

	if (argc != 1) {
		add_adv_usage();
		goto done;
	}

	if (uuid_bytes)
		uuid_bytes += 2;

	instance = strtol(argv[0], NULL, 0);

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	cp_len = sizeof(*cp) + uuid_bytes + adv_len + scan_rsp_len;
	cp = malloc0(cp_len);
	if (!cp)
		goto done;

	cp->instance = instance;
	put_le32(flags, &cp->flags);
	put_le16(timeout, &cp->timeout);
	put_le16(duration, &cp->duration);
	cp->adv_data_len = adv_len + uuid_bytes;
	cp->scan_rsp_len = scan_rsp_len;

	if (uuid_bytes) {
		cp->data[0] = uuid_bytes - 1;
		cp->data[1] = uuid_type == SDP_UUID16 ? 0x03 : 0x07;
		memcpy(cp->data + 2, uuids, uuid_bytes - 2);
	}

	memcpy(cp->data + uuid_bytes, adv_data, adv_len);
	memcpy(cp->data + uuid_bytes + adv_len, scan_rsp, scan_rsp_len);

	if (!mgmt_send(mgmt, MGMT_OP_ADD_ADVERTISING, index, cp_len, cp,
						add_adv_rsp, NULL, NULL)) {
		error("Unable to send \"Add Advertising\" command");
		goto done;
	}

	quit = false;

done:
	free(adv_data);
	free(scan_rsp);
	free(cp);

	if (quit)
		bt_shell_noninteractive_quit(success ? EXIT_SUCCESS : EXIT_FAILURE);
}

static void rm_adv_rsp(uint8_t status, uint16_t len, const void *param,
								void *user_data)
{
	const struct mgmt_rp_remove_advertising *rp = param;

	if (status != 0) {
		error("Remove Advertising failed with status 0x%02x (%s)",
						status, mgmt_errstr(status));
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	if (len != sizeof(*rp)) {
		error("Invalid Remove Advertising response length (%u)", len);
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	print("Instance removed: %u", rp->instance);

	return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static void cmd_rm_adv(int argc, char **argv)
{
	struct mgmt_cp_remove_advertising cp;
	uint8_t instance;
	uint16_t index;

	instance = strtol(argv[1], NULL, 0);

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

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

	cp.instance = instance;

	if (!mgmt_send(mgmt, MGMT_OP_REMOVE_ADVERTISING, index, sizeof(cp), &cp,
						rm_adv_rsp, NULL, NULL)) {
		error("Unable to send \"Remove Advertising\" command");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void cmd_clr_adv(int argc, char **argv)
{
	char *all_instances = "0";
	char *rm_argv[] = { "rm-adv", all_instances, NULL };

	cmd_rm_adv(2, rm_argv);
}

static void appearance_rsp(uint8_t status, uint16_t len, const void *param,
							void *user_data)
{
	if (status != 0)
		error("Could not set Appearance with status 0x%02x (%s)",
						status, mgmt_errstr(status));
	else
		print("Appearance successfully set");

	bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static void cmd_appearance(int argc, char **argv)
{
	struct mgmt_cp_set_appearance cp;
	uint16_t index;

	index = mgmt_index;
	if (index == MGMT_INDEX_NONE)
		index = 0;

	cp.appearance = cpu_to_le16(strtol(argv[1], NULL, 0));

	if (mgmt_send(mgmt, MGMT_OP_SET_APPEARANCE, index, sizeof(cp), &cp,
					appearance_rsp, NULL, NULL) == 0) {
		error("Unable to send appearance cmd");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}
}

static void register_mgmt_callbacks(struct mgmt *mgmt, uint16_t index)
{
	mgmt_register(mgmt, MGMT_EV_CONTROLLER_ERROR, index, controller_error,
								NULL, NULL);
	mgmt_register(mgmt, MGMT_EV_INDEX_ADDED, index, index_added,
								NULL, NULL);
	mgmt_register(mgmt, MGMT_EV_INDEX_REMOVED, index, index_removed,
								NULL, NULL);
	mgmt_register(mgmt, MGMT_EV_NEW_SETTINGS, index, new_settings,
								NULL, NULL);
	mgmt_register(mgmt, MGMT_EV_DISCOVERING, index, discovering,
								NULL, NULL);
	mgmt_register(mgmt, MGMT_EV_NEW_LINK_KEY, index, new_link_key,
								NULL, NULL);
	mgmt_register(mgmt, MGMT_EV_DEVICE_CONNECTED, index, connected,
								NULL, NULL);
	mgmt_register(mgmt, MGMT_EV_DEVICE_DISCONNECTED, index, disconnected,
								NULL, NULL);
	mgmt_register(mgmt, MGMT_EV_CONNECT_FAILED, index, conn_failed,
								NULL, NULL);
	mgmt_register(mgmt, MGMT_EV_AUTH_FAILED, index, auth_failed,
								NULL, NULL);
	mgmt_register(mgmt, MGMT_EV_CLASS_OF_DEV_CHANGED, index,
					class_of_dev_changed, NULL, NULL);
	mgmt_register(mgmt, MGMT_EV_LOCAL_NAME_CHANGED, index,
					local_name_changed, NULL, NULL);
	mgmt_register(mgmt, MGMT_EV_DEVICE_FOUND, index, device_found,
								mgmt, NULL);
	mgmt_register(mgmt, MGMT_EV_PIN_CODE_REQUEST, index, request_pin,
								mgmt, NULL);
	mgmt_register(mgmt, MGMT_EV_USER_CONFIRM_REQUEST, index, user_confirm,
								mgmt, NULL);
	mgmt_register(mgmt, MGMT_EV_USER_PASSKEY_REQUEST, index,
						request_passkey, mgmt, NULL);
	mgmt_register(mgmt, MGMT_EV_PASSKEY_NOTIFY, index,
						passkey_notify, mgmt, NULL);
	mgmt_register(mgmt, MGMT_EV_UNCONF_INDEX_ADDED, index,
					unconf_index_added, NULL, NULL);
	mgmt_register(mgmt, MGMT_EV_UNCONF_INDEX_REMOVED, index,
					unconf_index_removed, NULL, NULL);
	mgmt_register(mgmt, MGMT_EV_NEW_CONFIG_OPTIONS, index,
					new_config_options, NULL, NULL);
	mgmt_register(mgmt, MGMT_EV_EXT_INDEX_ADDED, index,
					ext_index_added, NULL, NULL);
	mgmt_register(mgmt, MGMT_EV_EXT_INDEX_REMOVED, index,
					ext_index_removed, NULL, NULL);
	mgmt_register(mgmt, MGMT_EV_LOCAL_OOB_DATA_UPDATED, index,
					local_oob_data_updated, NULL, NULL);
	mgmt_register(mgmt, MGMT_EV_ADVERTISING_ADDED, index,
						advertising_added, NULL, NULL);
	mgmt_register(mgmt, MGMT_EV_ADVERTISING_REMOVED, index,
					advertising_removed, NULL, NULL);
}

static void cmd_select(int argc, char **argv)
{
	mgmt_cancel_all(mgmt);
	mgmt_unregister_all(mgmt);

	set_index(argv[1]);

	register_mgmt_callbacks(mgmt, mgmt_index);

	print("Selected index %u", mgmt_index);

	update_prompt(mgmt_index);
}

static const struct bt_shell_menu main_menu = {
	.name = "main",
	.entries = {
	{ "select",		"<index>",
		cmd_select,		"Select a different index"	},
	{ "version",		NULL,
		cmd_version,		"Get the MGMT Version"		},
	{ "commands",		NULL,
		cmd_commands,		"List supported commands"	},
	{ "config",		NULL,
		cmd_config,		"Show configuration info"	},
	{ "info",		NULL,
		cmd_info,		"Show controller info"		},
	{ "extinfo",		NULL,
		cmd_extinfo,		"Show extended controller info"	},
	{ "auto-power",		NULL,
		cmd_auto_power,		"Power all available features"	},
	{ "power",		"<on/off>",
		cmd_power,		"Toggle powered state"		},
	{ "discov",		"<yes/no/limited> [timeout]",
		cmd_discov,		"Toggle discoverable state"	},
	{ "connectable",	"<on/off>",
	cmd_connectable,		"Toggle connectable state"	},
	{ "fast-conn",		"<on/off>",
		cmd_fast_conn,		"Toggle fast connectable state"	},
	{ "bondable",		"<on/off>",
		cmd_bondable,		"Toggle bondable state"		},
	{ "pairable",		"<on/off>",
		cmd_bondable,		"Toggle bondable state"		},
	{ "linksec",		"<on/off>",
		cmd_linksec,		"Toggle link level security"	},
	{ "ssp",		"<on/off>",
		cmd_ssp,		"Toggle SSP mode"		},
	{ "sc",			"<on/off/only>",
		cmd_sc,			"Toogle SC support"		},
	{ "hs",			"<on/off>",
		cmd_hs,			"Toggle HS support"		},
	{ "le",			"<on/off>",
		cmd_le,			"Toggle LE support"		},
	{ "advertising",	"<on/off>",
	cmd_advertising,		"Toggle LE advertising",	},
	{ "bredr",		"<on/off>",
		cmd_bredr,		"Toggle BR/EDR support",	},
	{ "privacy",		"<on/off>",
		cmd_privacy,		"Toggle privacy support"	},
	{ "class",		"<major> <minor>",
		cmd_class,		"Set device major/minor class"	},
	{ "disconnect", 	"[-t type] <remote address>",
		cmd_disconnect,		"Disconnect device"		},
	{ "con",		NULL,
		cmd_con,		"List connections"		},
	{ "find",		"[-l|-b] [-L]",
		cmd_find,		"Discover nearby devices"	},
	{ "find-service",	"[-u UUID] [-r RSSI_Threshold] [-l|-b]",
		cmd_find_service,	"Discover nearby service"	},
	{ "stop-find",		"[-l|-b]",
		cmd_stop_find,		"Stop discovery"		},
	{ "name",		"<name> [shortname]",
		cmd_name,		"Set local name"		},
	{ "pair",		"[-c cap] [-t type] <remote address>",
		cmd_pair,		"Pair with a remote device"	},
	{ "cancelpair",		"[-t type] <remote address>",
		cmd_cancel_pair,	"Cancel pairing"		},
	{ "unpair",		"[-t type] <remote address>",
		cmd_unpair,		"Unpair device"			},
	{ "keys",		NULL,
		cmd_keys,		"Load Link Keys"		},
	{ "ltks",		NULL,
		cmd_ltks,		"Load Long Term Keys"		},
	{ "irks",		"[--local <index>] [--file <file path>]",
		cmd_irks,		"Load Identity Resolving Keys"	},
	{ "block",		"[-t type] <remote address>",
		cmd_block,		"Block Device"			},
	{ "unblock",		"[-t type] <remote address>",
		cmd_unblock,		"Unblock Device"		},
	{ "add-uuid",		"<UUID> <service class hint>",
		cmd_add_uuid,		"Add UUID"			},
	{ "rm-uuid",		"<UUID>",
		cmd_remove_uuid,	"Remove UUID"			},
	{ "clr-uuids",		NULL,
		cmd_clr_uuids,		"Clear UUIDs"			},
	{ "local-oob",		NULL,
		cmd_local_oob,		"Local OOB data"		},
	{ "remote-oob",		"[-t <addr_type>] [-r <rand192>] "
				"[-h <hash192>] [-R <rand256>] "
				"[-H <hash256>] <addr>",
		cmd_remote_oob,		"Remote OOB data"		},
	{ "did",		"<source>:<vendor>:<product>:<version>",
		cmd_did,		"Set Device ID"			},
	{ "static-addr",	"<address>",
		cmd_static_addr,	"Set static address"		},
	{ "public-addr",	"<address>",
		cmd_public_addr,	"Set public address"		},
	{ "ext-config",		"<on/off>",
		cmd_ext_config,		"External configuration"	},
	{ "debug-keys",		"<on/off>",
		cmd_debug_keys,		"Toogle debug keys"		},
	{ "conn-info",		"[-t type] <remote address>",
		cmd_conn_info,		"Get connection information"	},
	{ "io-cap",		"<cap>",
		cmd_io_cap,		"Set IO Capability"		},
	{ "scan-params",	"<interval> <window>",
		cmd_scan_params,	"Set Scan Parameters"		},
	{ "get-clock",		"[address]",
		cmd_clock_info,		"Get Clock Information"		},
	{ "add-device", 	"[-a action] [-t type] <address>",
		cmd_add_device,		"Add Device"			},
	{ "del-device", 	"[-t type] <address>",
		cmd_del_device,		"Remove Device"			},
	{ "clr-devices",	NULL,
		cmd_clr_devices,	"Clear Devices"			},
	{ "bredr-oob",		NULL,
		cmd_bredr_oob,		"Local OOB data (BR/EDR)"	},
	{ "le-oob",		NULL,
		cmd_le_oob,		"Local OOB data (LE)"		},
	{ "advinfo",		NULL,
		cmd_advinfo,		"Show advertising features"	},
	{ "advsize",		"[options] <instance_id>",
		cmd_advsize,		"Show advertising size info"	},
	{ "add-adv",		"[options] <instance_id>",
		cmd_add_adv,		"Add advertising instance"	},
	{ "rm-adv",		"<instance_id>",
		cmd_rm_adv,		"Remove advertising instance"	},
	{ "clr-adv",		NULL,
		cmd_clr_adv,		"Clear advertising instances"	},
	{ "appearance",		"<appearance>",
		cmd_appearance,		"Set appearance"		},
	{} },
};

static void mgmt_debug(const char *str, void *user_data)
{
	const char *prefix = user_data;

	print("%s%s", prefix, str);
}

static const char *index_option;

static struct option main_options[] = {
	{ "index",	1, 0, 'i' },
	{ 0, 0, 0, 0 }
};

static const char **optargs[] = {
	&index_option
};

static const char *help[] = {
	"Specify adapter index\n"
};

static const struct bt_shell_opt opt = {
	.options = main_options,
	.optno = sizeof(main_options) / sizeof(struct option),
	.optstr = "i:V",
	.optarg = optargs,
	.help = help,
};

int main(int argc, char *argv[])
{
	int status;

	bt_shell_init(argc, argv, &opt);
	bt_shell_set_menu(&main_menu);

	mgmt = mgmt_new_default();
	if (!mgmt) {
		fprintf(stderr, "Unable to open mgmt_socket\n");
		return EXIT_FAILURE;
	}

	if (getenv("MGMT_DEBUG"))
		mgmt_set_debug(mgmt, mgmt_debug, "mgmt: ", NULL);

	if (index_option)
		set_index(index_option);

	register_mgmt_callbacks(mgmt, mgmt_index);

	bt_shell_attach(fileno(stdin));
	update_prompt(mgmt_index);
	status = bt_shell_run();

	mgmt_cancel_all(mgmt);
	mgmt_unregister_all(mgmt);
	mgmt_unref(mgmt);

	return status;
}
