/*
 *  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 <readline/readline.h>
#include <readline/history.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 "client/display.h"
#include "src/shared/mainloop.h"
#include "src/shared/io.h"
#include "src/shared/util.h"
#include "src/shared/mgmt.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 bool interactive = false;

static char *saved_prompt = NULL;
static int saved_point = 0;

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

	if (saved_prompt) {
		free(saved_prompt);
		saved_prompt = strdup(str);
		return;
	}

	rl_set_prompt(str);
}

static void noninteractive_quit(int status)
{
	if (interactive)
		return;

	if (status == EXIT_SUCCESS)
		mainloop_exit_success();
	else
		mainloop_exit_failure();
}

#define print(fmt, arg...) do { \
	if (interactive) \
		rl_printf(fmt "\n", ## arg); \
	else \
		printf(fmt "\n", ## arg); \
} while (0)

#define error(fmt, arg...) do { \
	if (interactive) \
		rl_printf(COLOR_RED fmt "\n" COLOR_OFF, ## arg); \
	else \
		fprintf(stderr, fmt "\n", ## 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(uint16_t index, struct mgmt_irk_info *irk)
{
	char identity_path[PATH_MAX];
	char *addr, *key;
	unsigned int type;
	int n;
	FILE *fp;

	snprintf(identity_path, sizeof(identity_path),
			"/sys/kernel/debug/bluetooth/hci%u/identity", index);

	fp = fopen(identity_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 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 release_prompt(void)
{
	if (!interactive)
		return;

	memset(&prompt, 0, sizeof(prompt));
	prompt.index = MGMT_INDEX_NONE;

	if (!saved_prompt)
		return;

	/* This will cause rl_expand_prompt to re-run over the last prompt,
	 * but our prompt doesn't expand anyway.
	 */
	rl_set_prompt(saved_prompt);
	rl_replace_line("", 0);
	rl_point = saved_point;
	rl_redisplay();

	free(saved_prompt);
	saved_prompt = NULL;
}

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 (!memcmp(&ev->addr, &prompt.addr, sizeof(ev->addr)))
		release_prompt();

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

	if (!memcmp(&ev->addr, &prompt.addr, sizeof(ev->addr)))
		release_prompt();

	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 noninteractive_quit(EXIT_FAILURE);
	}

	print("PIN Reply successful");
}

static int mgmt_pin_reply(struct mgmt *mgmt, 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 noninteractive_quit(EXIT_FAILURE);
	}

	print("PIN Negative Reply successful");
}

static int mgmt_pin_neg_reply(struct mgmt *mgmt, 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 noninteractive_quit(EXIT_FAILURE);
	}

	print("User Confirm Reply successful");
}

static int mgmt_confirm_reply(struct mgmt *mgmt, 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 noninteractive_quit(EXIT_FAILURE);
	}

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

static int mgmt_confirm_neg_reply(struct mgmt *mgmt, 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 noninteractive_quit(EXIT_FAILURE);
	}

	print("User Passkey Reply successful");
}

static int mgmt_passkey_reply(struct mgmt *mgmt, 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 noninteractive_quit(EXIT_FAILURE);
	}

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

static int mgmt_passkey_neg_reply(struct mgmt *mgmt, 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 bool prompt_input(const char *input)
{
	size_t len;

	if (!prompt.req)
		return false;

	len = strlen(input);

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

	release_prompt();

	return true;
}

static void interactive_prompt(const char *msg)
{
	if (saved_prompt)
		return;

	saved_prompt = strdup(rl_prompt);
	if (!saved_prompt)
		return;

	saved_point = rl_point;

	rl_set_prompt("");
	rl_redisplay();

	rl_set_prompt(msg);

	rl_replace_line("", 0);
	rl_redisplay();
}

static size_t get_input(char *buf, size_t buf_len)
{
	size_t len;

	if (!fgets(buf, buf_len, stdin))
		return 0;

	len = strlen(buf);

	/* Remove trailing white-space */
	while (len && isspace(buf[len - 1]))
		buf[--len] = '\0';

	return len;
}

static void ask(uint16_t index, uint16_t req, const struct mgmt_addr_info *addr,
						const char *fmt, ...)
{
	char msg[256], buf[18];
	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);

	if (interactive) {
		interactive_prompt(msg);
		va_end(ap);
		return;
	}

	printf("%s", msg);
	fflush(stdout);

	memset(buf, 0, sizeof(buf));
	get_input(buf, sizeof(buf));
	prompt_input(buf);
}

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:
	noninteractive_quit(EXIT_SUCCESS);
}

static void cmd_version(struct mgmt *mgmt, uint16_t index, 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 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:
	noninteractive_quit(EXIT_SUCCESS);
}

static void cmd_commands(struct mgmt *mgmt, uint16_t index, 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 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;

	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 noninteractive_quit(EXIT_FAILURE);
	}

	if (len < sizeof(*rp)) {
		error("Too small index list reply (%u bytes)", len);
		return 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 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 noninteractive_quit(EXIT_FAILURE);
		}

		pending_index++;
	}

	if (!count)
		noninteractive_quit(EXIT_SUCCESS);
}

static void cmd_config(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
{
	if (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 noninteractive_quit(EXIT_FAILURE);
		}

		return;
	}

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

	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;

	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 noninteractive_quit(EXIT_FAILURE);
	}

	if (len < sizeof(*rp)) {
		error("Too small index list reply (%u bytes)", len);
		return 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 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 noninteractive_quit(EXIT_FAILURE);
		}

		pending_index++;
	}

	if (!count)
		noninteractive_quit(EXIT_SUCCESS);
}

static void cmd_info(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
{
	if (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 noninteractive_quit(EXIT_FAILURE);
		}

		return;
	}

	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 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 noninteractive_quit(EXIT_FAILURE);
	}

	if (len < sizeof(*rp)) {
		error("Too small ext index list reply (%u bytes)", len);
		return 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 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_INFO,
						index, 0, NULL, info_rsp,
						UINT_TO_PTR(index), NULL)) {
				error("Unable to send read_info cmd");
				return 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 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)
		noninteractive_quit(EXIT_SUCCESS);
}

static void cmd_extinfo(struct mgmt *mgmt, uint16_t index,
						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 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);

	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 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 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 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 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 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 noninteractive_quit(EXIT_FAILURE);
	}
}

static void cmd_auto_power(struct mgmt *mgmt, uint16_t index,
						int argc, char **argv)
{
	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 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:
	noninteractive_quit(EXIT_SUCCESS);
}

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

	if (argc < 2) {
		print("Specify \"on\" or \"off\"");
		return noninteractive_quit(EXIT_FAILURE);
	}

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

	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 noninteractive_quit(EXIT_FAILURE);
	}
}

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

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

	if (argc < 2) {
		print("Usage: %s <yes/no/limited> [timeout]", argv[0]);
		return noninteractive_quit(EXIT_FAILURE);
	}

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

	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 noninteractive_quit(EXIT_FAILURE);
	}
}

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

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

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

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

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

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

	if (argc < 2) {
		print("Specify \"on\" or \"off\" or \"only\"");
		return noninteractive_quit(EXIT_FAILURE);
	}

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

	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 noninteractive_quit(EXIT_FAILURE);
	}
}

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

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

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

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

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

	if (argc < 2) {
		print("Specify \"on\" or \"off\"");
		return noninteractive_quit(EXIT_FAILURE);
	}

	if (strcasecmp(argv[1], "on") == 0 || strcasecmp(argv[1], "yes") == 0)
		cp.privacy = 0x01;
	else if (strcasecmp(argv[1], "off") == 0)
		cp.privacy = 0x00;
	else
		cp.privacy = atoi(argv[1]);

	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 noninteractive_quit(EXIT_FAILURE);
		}
	} else {
		int fd;

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

		if (read(fd, cp.irk, sizeof(cp.irk)) != sizeof(cp.irk)) {
			error("Reading from urandom failed");
			close(fd);
			return 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 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 noninteractive_quit(EXIT_FAILURE);
	}

	if (len != sizeof(*rp)) {
		error("Unexpected %s len %u", mgmt_opstr(op), len);
		return 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]);

	noninteractive_quit(EXIT_SUCCESS);
}

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

	if (argc < 3) {
		print("Usage: %s <major> <minor>", argv[0]);
		return noninteractive_quit(EXIT_FAILURE);
	}

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

	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 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 noninteractive_quit(EXIT_FAILURE);
	}

	if (len != sizeof(*rp)) {
		error("Invalid disconnect response length (%u)", len);
		return 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));

	noninteractive_quit(EXIT_SUCCESS);
}

static void disconnect_usage(void)
{
	print("Usage: disconnect [-t type] <remote address>");
}

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

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

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

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

	if (argc < 1) {
		disconnect_usage();
		return noninteractive_quit(EXIT_FAILURE);
	}

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

	noninteractive_quit(EXIT_SUCCESS);
}

static void cmd_con(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
{
	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 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 noninteractive_quit(EXIT_FAILURE);
	}

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

static void find_service_usage(void)
{
	print("Usage: find-service [-u UUID] [-r RSSI_Threshold] [-l|-b]");
}

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(struct mgmt *mgmt, uint16_t index, 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;

	if (index == MGMT_INDEX_NONE)
		index = 0;

	rssi = 127;
	count = 0;

	if (argc == 1) {
		find_service_usage();
		return noninteractive_quit(EXIT_FAILURE);
	}

	while ((opt = getopt_long(argc, argv, "+lbu:r:p: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 noninteractive_quit(EXIT_FAILURE);
			}

			if (bt_string2uuid(&uuid, optarg) < 0) {
				print("Invalid UUID: %s", optarg);
				optind = 0;
				return 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':
			find_service_usage();
			optind = 0;
			return noninteractive_quit(EXIT_SUCCESS);
		default:
			find_service_usage();
			optind = 0;
			return noninteractive_quit(EXIT_FAILURE);
		}
	}

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

	if (argc > 0) {
		find_service_usage();
		return noninteractive_quit(EXIT_FAILURE);
	}

	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 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 noninteractive_quit(EXIT_FAILURE);
	}

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

static void find_usage(void)
{
	print("Usage: find [-l|-b]>");
}

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(struct mgmt *mgmt, uint16_t index, 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;

	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':
			find_usage();
			optind = 0;
			return noninteractive_quit(EXIT_SUCCESS);
		default:
			find_usage();
			optind = 0;
			return 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 noninteractive_quit(EXIT_FAILURE);
	}
}

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

	printf("Discovery stopped\n");
	discovery = false;

	noninteractive_quit(EXIT_SUCCESS);
}

static void stop_find_usage(void)
{
	printf("Usage: btmgmt stop-find [-l|-b]>\n");
}

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(struct mgmt *mgmt, uint16_t index, int argc,
			  char **argv)
{
	struct mgmt_cp_stop_discovery cp;
	uint8_t type = SCAN_TYPE_DUAL;
	int opt;

	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:
			stop_find_usage();
			optind = 0;
			exit(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) {
		fprintf(stderr, "Unable to send stop_discovery cmd\n");
		exit(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));

	noninteractive_quit(EXIT_SUCCESS);
}

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

	if (argc < 2) {
		print("Usage: %s <name> [shortname]", argv[0]);
		return noninteractive_quit(EXIT_FAILURE);
	}

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

	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 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 noninteractive_quit(EXIT_FAILURE);
	}

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

	if (!memcmp(&rp->addr, &prompt.addr, sizeof(rp->addr)))
		release_prompt();

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

	noninteractive_quit(EXIT_SUCCESS);
}

static void pair_usage(void)
{
	print("Usage: pair [-c cap] [-t type] <remote address>");
}

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(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
{
	struct mgmt_cp_pair_device cp;
	uint8_t cap = 0x01;
	uint8_t type = BDADDR_BREDR;
	char addr[18];
	int opt;

	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':
			pair_usage();
			optind = 0;
			return noninteractive_quit(EXIT_SUCCESS);
		default:
			pair_usage();
			optind = 0;
			return noninteractive_quit(EXIT_FAILURE);
		}
	}

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

	if (argc < 1) {
		pair_usage();
		return noninteractive_quit(EXIT_FAILURE);
	}

	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 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 noninteractive_quit(EXIT_FAILURE);
	}

	if (len != sizeof(*rp)) {
		error("Unexpected cancel_pair_rsp len %u", len);
		return 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);

	noninteractive_quit(EXIT_SUCCESS);
}

static void cancel_pair_usage(void)
{
	print("Usage: cancelpair [-t type] <remote address>");
}

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

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

	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':
			cancel_pair_usage();
			optind = 0;
			return noninteractive_quit(EXIT_SUCCESS);
		default:
			cancel_pair_usage();
			optind = 0;
			return noninteractive_quit(EXIT_FAILURE);
		}
	}

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

	if (argc < 1) {
		cancel_pair_usage();
		return noninteractive_quit(EXIT_FAILURE);
	}

	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 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 noninteractive_quit(EXIT_FAILURE);
	}

	if (len != sizeof(*rp)) {
		error("Unexpected unpair_device_rsp len %u", len);
		return 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);

	noninteractive_quit(EXIT_SUCCESS);
}

static void unpair_usage(void)
{
	print("Usage: unpair [-t type] <remote address>");
}

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

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

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

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

	if (argc < 1) {
		unpair_usage();
		return noninteractive_quit(EXIT_FAILURE);
	}

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

	noninteractive_quit(EXIT_SUCCESS);
}

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

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

	noninteractive_quit(EXIT_SUCCESS);
}

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

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

	noninteractive_quit(EXIT_SUCCESS);
}

static void irks_usage(void)
{
	print("Usage: irks [--local]");
}

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

#define MAX_IRKS 4

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

	if (index == MGMT_INDEX_NONE)
		index = 0;

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

	while ((opt = getopt_long(argc, argv, "+l:h",
					irks_options, NULL)) != -1) {
		switch (opt) {
		case 'l':
			if (count >= MAX_IRKS) {
				error("Number of IRKs exceeded");
				optind = 0;
				return noninteractive_quit(EXIT_FAILURE);
			}
			if (strlen(optarg) > 3 &&
					strncasecmp(optarg, "hci", 3) == 0)
				local_index = atoi(optarg + 3);
			else
				local_index = atoi(optarg);
			if (!load_identity(local_index, &cp->irks[count])) {
				error("Unable to load identity");
				optind = 0;
				return noninteractive_quit(EXIT_FAILURE);
			}
			count++;
			break;
		case 'h':
			irks_usage();
			optind = 0;
			return noninteractive_quit(EXIT_SUCCESS);
		default:
			irks_usage();
			optind = 0;
			return noninteractive_quit(EXIT_FAILURE);
		}
	}

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

	if (argc > 0) {
		irks_usage();
		return noninteractive_quit(EXIT_FAILURE);
	}

	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 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 noninteractive_quit(EXIT_FAILURE);
	}

	if (len != sizeof(*rp)) {
		error("Unexpected %s len %u", mgmt_opstr(op), len);
		return 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);

	noninteractive_quit(EXIT_SUCCESS);
}

static void block_usage(void)
{
	print("Usage: block [-t type] <remote address>");
}

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

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

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

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

	if (argc < 1) {
		block_usage();
		return noninteractive_quit(EXIT_FAILURE);
	}

	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 noninteractive_quit(EXIT_FAILURE);
	}
}

static void unblock_usage(void)
{
	print("Usage: unblock [-t type] <remote address>");
}

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

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

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

	if (argc < 1) {
		unblock_usage();
		return noninteractive_quit(EXIT_FAILURE);
	}

	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 noninteractive_quit(EXIT_FAILURE);
	}
}

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

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

	if (index == MGMT_INDEX_NONE)
		index = 0;

	if (bt_string2uuid(&uuid, argv[1]) < 0) {
		print("Invalid UUID: %s", argv[1]);
		return 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 noninteractive_quit(EXIT_FAILURE);
	}
}

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

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

	if (index == MGMT_INDEX_NONE)
		index = 0;

	if (bt_string2uuid(&uuid, argv[1]) < 0) {
		print("Invalid UUID: %s", argv[1]);
		return 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 noninteractive_quit(EXIT_FAILURE);
	}
}

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

	cmd_remove_uuid(mgmt, index, 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 noninteractive_quit(EXIT_FAILURE);
	}

	if (len < sizeof(*rp)) {
		error("Too small (%u bytes) read_local_oob rsp", len);
		return 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 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);

	noninteractive_quit(EXIT_SUCCESS);
}

static void cmd_local_oob(struct mgmt *mgmt, uint16_t index,
						int argc, char **argv)
{
	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 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 void remote_oob_usage(void)
{
	print("Usage: remote-oob [-t <addr_type>] "
		"[-r <rand192>] [-h <hash192>] [-R <rand256>] [-H <hash256>] "
		"<addr>");
}

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

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

	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:
			remote_oob_usage();
			return noninteractive_quit(EXIT_FAILURE);
		}
	}

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

	if (argc < 1) {
		remote_oob_usage();
		return noninteractive_quit(EXIT_FAILURE);
	}

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

	noninteractive_quit(EXIT_SUCCESS);
}

static void did_usage(void)
{
	print("Usage: did <source>:<vendor>:<product>:<version>");
	print("       possible source values: bluetooth, usb");
}

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

	if (argc < 2) {
		did_usage();
		return noninteractive_quit(EXIT_FAILURE);
	}

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

	did_usage();
	return noninteractive_quit(EXIT_FAILURE);

done:
	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 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");

	noninteractive_quit(EXIT_SUCCESS);
}

static void static_addr_usage(void)
{
	print("Usage: static-addr <address>");
}

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

	if (argc < 2) {
		static_addr_usage();
		return noninteractive_quit(EXIT_FAILURE);
	}

	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 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 noninteractive_quit(EXIT_FAILURE);
	}

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

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

	noninteractive_quit(EXIT_SUCCESS);
}

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

	if (argc < 2) {
		print("Usage: public-addr <address>");
		return noninteractive_quit(EXIT_FAILURE);
	}

	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 noninteractive_quit(EXIT_FAILURE);
	}
}

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

	if (argc < 2) {
		print("Specify \"on\" or \"off\"");
		return noninteractive_quit(EXIT_FAILURE);
	}

	if (strcasecmp(argv[1], "on") == 0 || strcasecmp(argv[1], "yes") == 0)
		cp.config = 0x01;
	else if (strcasecmp(argv[1], "off") == 0)
		cp.config = 0x00;
	else
		cp.config = atoi(argv[1]);

	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 noninteractive_quit(EXIT_FAILURE);
	}
}

static void cmd_debug_keys(struct mgmt *mgmt, uint16_t index,
						int argc, char **argv)
{
	cmd_setting(mgmt, index, 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 noninteractive_quit(EXIT_FAILURE);
	}

	if (len < sizeof(*rp)) {
		error("Unexpected Get Conn Info len %u", len);
		return 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);
	}

	noninteractive_quit(EXIT_SUCCESS);
}

static void conn_info_usage(void)
{
	print("Usage: conn-info [-t type] <remote address>");
}

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

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

	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':
			conn_info_usage();
			return noninteractive_quit(EXIT_SUCCESS);
		default:
			conn_info_usage();
			return noninteractive_quit(EXIT_FAILURE);
		}
	}

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

	if (argc < 1) {
		conn_info_usage();
		return noninteractive_quit(EXIT_FAILURE);
	}

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

	noninteractive_quit(EXIT_SUCCESS);
}

static void io_cap_usage(void)
{
	print("Usage: io-cap <cap>");
}

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

	if (argc < 2) {
		io_cap_usage();
		return noninteractive_quit(EXIT_FAILURE);
	}

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

	noninteractive_quit(EXIT_SUCCESS);
}

static void scan_params_usage(void)
{
	print("Usage: scan-params <interval> <window>");
}

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

	if (argc < 3) {
		scan_params_usage();
		return noninteractive_quit(EXIT_FAILURE);
	}

	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 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 noninteractive_quit(EXIT_FAILURE);
	}

	if (status) {
		error("Get Clock Info failed with status 0x%02x (%s)",
						status, mgmt_errstr(status));
		return 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));

	noninteractive_quit(EXIT_SUCCESS);
}

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

	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 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));
	noninteractive_quit(EXIT_SUCCESS);
}

static void add_device_usage(void)
{
	print("Usage: add-device [-a action] [-t type] <address>");
}

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(struct mgmt *mgmt, uint16_t index,
						int argc, char **argv)
{
	struct mgmt_cp_add_device cp;
	uint8_t action = 0x00;
	uint8_t type = BDADDR_BREDR;
	char addr[18];
	int opt;

	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':
			add_device_usage();
			return noninteractive_quit(EXIT_SUCCESS);
		default:
			add_device_usage();
			return noninteractive_quit(EXIT_FAILURE);
		}
	}

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

	if (argc < 1) {
		add_device_usage();
		return noninteractive_quit(EXIT_FAILURE);
	}

	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 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));
	noninteractive_quit(EXIT_SUCCESS);
}

static void del_device_usage(void)
{
	print("Usage: del-device [-t type] <address>");
}

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

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

	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':
			del_device_usage();
			return noninteractive_quit(EXIT_SUCCESS);
		default:
			del_device_usage();
			return noninteractive_quit(EXIT_FAILURE);
		}
	}

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

	if (argc < 1) {
		del_device_usage();
		return noninteractive_quit(EXIT_FAILURE);
	}

	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 noninteractive_quit(EXIT_FAILURE);
	}
}

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

	cmd_del_device(mgmt, index, 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 noninteractive_quit(EXIT_FAILURE);
	}

	if (len < sizeof(*rp)) {
		error("Too small (%u bytes) read_local_oob_ext rsp", len);
		return 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 noninteractive_quit(EXIT_FAILURE);
	}

	print_eir(rp->eir, eir_len);

	noninteractive_quit(EXIT_SUCCESS);
}

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

	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 noninteractive_quit(EXIT_FAILURE);
	}
}

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

	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 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 noninteractive_quit(EXIT_FAILURE);
	}

	if (len < sizeof(*rp)) {
		error("Too small adv features reply (%u bytes)", len);
		return 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 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 noninteractive_quit(EXIT_SUCCESS);
}

static void cmd_advinfo(struct mgmt *mgmt, uint16_t index,
						int argc, char **argv)
{
	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 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 noninteractive_quit(EXIT_FAILURE);
	}

	if (len < sizeof(*rp)) {
		error("Too small adv size info reply (%u bytes)", len);
		return 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 noninteractive_quit(EXIT_SUCCESS);
}

static void advsize_usage(void)
{
	print("Usage: advsize [options] <instance_id>\nOptions:\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");
}

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' },
	{ 0, 0, 0, 0}
};

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

	while ((opt = getopt_long(argc, argv, "+cglmph",
						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;
		default:
			advsize_usage();
			return noninteractive_quit(EXIT_FAILURE);
		}
	}

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

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

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

	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 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 noninteractive_quit(EXIT_FAILURE);
	}

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

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

	return noninteractive_quit(EXIT_SUCCESS);
}

static void add_adv_usage(void)
{
	print("Usage: add-adv [options] <instance_id>\nOptions:\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 -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(struct mgmt *mgmt, uint16_t index,
							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;

	while ((opt = getopt_long(argc, argv, "+u:d:s:t:D:cglmph",
						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 'h':
			success = true;
		default:
			add_adv_usage();
			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);

	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)
		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 noninteractive_quit(EXIT_FAILURE);
	}

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

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

	return noninteractive_quit(EXIT_SUCCESS);
}

static void rm_adv_usage(void)
{
	print("Usage: rm-adv <instance_id>");
}

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

	if (argc != 2) {
		rm_adv_usage();
		return noninteractive_quit(EXIT_FAILURE);
	}

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

	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 noninteractive_quit(EXIT_FAILURE);
	}
}

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

	cmd_rm_adv(mgmt, index, 2, rm_argv);
}

struct cmd_info {
	char *cmd;
	void (*func)(struct mgmt *mgmt, uint16_t index, int argc, char **argv);
	char *doc;
	char * (*gen) (const char *text, int state);
	void (*disp) (char **matches, int num_matches, int max_length);
};

static struct cmd_info all_cmd[] = {
	{ "version",	cmd_version,	"Get the MGMT Version"		},
	{ "commands",	cmd_commands,	"List supported commands"	},
	{ "config",	cmd_config,	"Show configuration info"	},
	{ "info",	cmd_info,	"Show controller info"		},
	{ "extinfo",	cmd_extinfo,	"Show extended controller info"	},
	{ "auto-power",	cmd_auto_power,	"Power all available features"	},
	{ "power",	cmd_power,	"Toggle powered state"		},
	{ "discov",	cmd_discov,	"Toggle discoverable state"	},
	{ "connectable",cmd_connectable,"Toggle connectable state"	},
	{ "fast-conn",	cmd_fast_conn,	"Toggle fast connectable state"	},
	{ "bondable",	cmd_bondable,	"Toggle bondable state"		},
	{ "pairable",	cmd_bondable,	"Toggle bondable state"		},
	{ "linksec",	cmd_linksec,	"Toggle link level security"	},
	{ "ssp",	cmd_ssp,	"Toggle SSP mode"		},
	{ "sc",		cmd_sc,		"Toogle SC support"		},
	{ "hs",		cmd_hs,		"Toggle HS support"		},
	{ "le",		cmd_le,		"Toggle LE support"		},
	{ "advertising",cmd_advertising,"Toggle LE advertising",	},
	{ "bredr",	cmd_bredr,	"Toggle BR/EDR support",	},
	{ "privacy",	cmd_privacy,	"Toggle privacy support"	},
	{ "class",	cmd_class,	"Set device major/minor class"	},
	{ "disconnect", cmd_disconnect, "Disconnect device"		},
	{ "con",	cmd_con,	"List connections"		},
	{ "find",	cmd_find,	"Discover nearby devices"	},
	{ "find-service", cmd_find_service, "Discover nearby service"	},
	{ "stop-find",	cmd_stop_find,	"Stop discovery"		},
	{ "name",	cmd_name,	"Set local name"		},
	{ "pair",	cmd_pair,	"Pair with a remote device"	},
	{ "cancelpair",	cmd_cancel_pair,"Cancel pairing"		},
	{ "unpair",	cmd_unpair,	"Unpair device"			},
	{ "keys",	cmd_keys,	"Load Link Keys"		},
	{ "ltks",	cmd_ltks,	"Load Long Term Keys"		},
	{ "irks",	cmd_irks,	"Load Identity Resolving Keys"	},
	{ "block",	cmd_block,	"Block Device"			},
	{ "unblock",	cmd_unblock,	"Unblock Device"		},
	{ "add-uuid",	cmd_add_uuid,	"Add UUID"			},
	{ "rm-uuid",	cmd_remove_uuid,"Remove UUID"			},
	{ "clr-uuids",	cmd_clr_uuids,	"Clear UUIDs"			},
	{ "local-oob",	cmd_local_oob,	"Local OOB data"		},
	{ "remote-oob",	cmd_remote_oob,	"Remote OOB data"		},
	{ "did",	cmd_did,	"Set Device ID"			},
	{ "static-addr",cmd_static_addr,"Set static address"		},
	{ "public-addr",cmd_public_addr,"Set public address"		},
	{ "ext-config",	cmd_ext_config,	"External configuration"	},
	{ "debug-keys",	cmd_debug_keys,	"Toogle debug keys"		},
	{ "conn-info",	cmd_conn_info,	"Get connection information"	},
	{ "io-cap",	cmd_io_cap,	"Set IO Capability"		},
	{ "scan-params",cmd_scan_params,"Set Scan Parameters"		},
	{ "get-clock",	cmd_clock_info,	"Get Clock Information"		},
	{ "add-device", cmd_add_device, "Add Device"			},
	{ "del-device", cmd_del_device, "Remove Device"			},
	{ "clr-devices",cmd_clr_devices,"Clear Devices"			},
	{ "bredr-oob",	cmd_bredr_oob,	"Local OOB data (BR/EDR)"	},
	{ "le-oob",	cmd_le_oob,	"Local OOB data (LE)"		},
	{ "advinfo",	cmd_advinfo,	"Show advertising features"	},
	{ "advsize",	cmd_advsize,	"Show advertising size info"	},
	{ "add-adv",	cmd_add_adv,	"Add advertising instance"	},
	{ "rm-adv",	cmd_rm_adv,	"Remove advertising instance"	},
	{ "clr-adv",	cmd_clr_adv,	"Clear advertising instances"	},
};

static void cmd_quit(struct mgmt *mgmt, uint16_t index,
						int argc, char **argv)
{
	mainloop_exit_success();
}

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(struct mgmt *mgmt, uint16_t index,
						int argc, char **argv)
{
	if (argc != 2) {
		error("Usage: select <index>");
		return;
	}

	mgmt_cancel_all(mgmt);
	mgmt_unregister_all(mgmt);

	if (!strcmp(argv[1], "none") || !strcmp(argv[1], "any") ||
						!strcmp(argv[1], "all"))
		mgmt_index = MGMT_INDEX_NONE;
	else if (!strncmp(argv[1], "hci", 3))
		mgmt_index = atoi(&argv[1][3]);
	else
		mgmt_index = atoi(argv[1]);

	register_mgmt_callbacks(mgmt, mgmt_index);

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

	update_prompt(mgmt_index);
}

static struct cmd_info interactive_cmd[] = {
	{ "select",	cmd_select,	"Select a different index"	},
	{ "quit",	cmd_quit,	"Exit program"			},
	{ "exit",	cmd_quit,	"Exit program"			},
	{ "help",	NULL,		"List supported commands"	},
};

static char *cmd_generator(const char *text, int state)
{
	static size_t i, j, len;
	const char *cmd;

	if (!state) {
		i = 0;
		j = 0;
		len = strlen(text);
	}

	while (i < NELEM(all_cmd)) {
		cmd = all_cmd[i++].cmd;

		if (!strncmp(cmd, text, len))
			return strdup(cmd);
	}

	while (j < NELEM(interactive_cmd)) {
		cmd = interactive_cmd[j++].cmd;

		if (!strncmp(cmd, text, len))
			return strdup(cmd);
	}

	return NULL;
}

static char **cmd_completion(const char *text, int start, int end)
{
	char **matches = NULL;

	if (start > 0) {
		unsigned int i;

		for (i = 0; i < NELEM(all_cmd); i++) {
			struct cmd_info *c = &all_cmd[i];

			if (strncmp(c->cmd, rl_line_buffer, start - 1))
				continue;

			if (!c->gen)
				continue;

			rl_completion_display_matches_hook = c->disp;
			matches = rl_completion_matches(text, c->gen);
			break;
		}
	} else {
		rl_completion_display_matches_hook = NULL;
		matches = rl_completion_matches(text, cmd_generator);
	}

	if (!matches)
		rl_attempted_completion_over = 1;

	return matches;
}

static struct cmd_info *find_cmd(const char *cmd, struct cmd_info table[],
							size_t cmd_count)
{
	size_t i;

	for (i = 0; i < cmd_count; i++) {
		if (!strcmp(table[i].cmd, cmd))
			return &table[i];
	}

	return NULL;
}

static void rl_handler(char *input)
{
	struct cmd_info *c;
	wordexp_t w;
	char *cmd, **argv;
	size_t argc, i;

	if (!input) {
		rl_insert_text("quit");
		rl_redisplay();
		rl_crlf();
		mainloop_quit();
		return;
	}

	if (!strlen(input))
		goto done;

	if (prompt_input(input))
		goto done;

	add_history(input);

	if (wordexp(input, &w, WRDE_NOCMD))
		goto done;

	if (w.we_wordc == 0)
		goto free_we;

	cmd = w.we_wordv[0];
	argv = w.we_wordv;
	argc = w.we_wordc;

	c = find_cmd(cmd, all_cmd, NELEM(all_cmd));
	if (!c && interactive)
		c = find_cmd(cmd, interactive_cmd, NELEM(interactive_cmd));

	if (c && c->func) {
		c->func(mgmt, mgmt_index, argc, argv);
		goto free_we;
	}

	if (strcmp(cmd, "help")) {
		print("Invalid command");
		goto free_we;
	}

	print("Available commands:");

	for (i = 0; i < NELEM(all_cmd); i++) {
		c = &all_cmd[i];
		if (c->doc)
			print("  %s %-*s %s", c->cmd,
				(int)(25 - strlen(c->cmd)), "", c->doc ? : "");
	}

	if (!interactive)
		goto free_we;

	for (i = 0; i < NELEM(interactive_cmd); i++) {
		c = &interactive_cmd[i];
		if (c->doc)
			print("  %s %-*s %s", c->cmd,
				(int)(25 - strlen(c->cmd)), "", c->doc ? : "");
	}

free_we:
	wordfree(&w);
done:
	free(input);
}

static void usage(void)
{
	unsigned int i;

	printf("btmgmt ver %s\n", VERSION);
	printf("Usage:\n"
		"\tbtmgmt [options] <command> [command parameters]\n");

	printf("Options:\n"
		"\t--index <id>\tSpecify adapter index\n"
		"\t--verbose\tEnable extra logging\n"
		"\t--help\tDisplay help\n");

	printf("Commands:\n");
	for (i = 0; i < NELEM(all_cmd); i++)
		printf("\t%-15s\t%s\n", all_cmd[i].cmd, all_cmd[i].doc);

	printf("\n"
		"For more information on the usage of each command use:\n"
		"\tbtmgmt <command> --help\n" );
}

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

static bool prompt_read(struct io *io, void *user_data)
{
	rl_callback_read_char();
	return true;
}

static struct io *setup_stdin(void)
{
	struct io *io;

	io = io_new(STDIN_FILENO);
	if (!io)
		return io;

	io_set_read_handler(io, prompt_read, NULL, NULL);

	return io;
}

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

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

int main(int argc, char *argv[])
{
	struct io *input;
	uint16_t index = MGMT_INDEX_NONE;
	int status, opt;

	while ((opt = getopt_long(argc, argv, "+hi:",
						main_options, NULL)) != -1) {
		switch (opt) {
		case 'i':
			if (strlen(optarg) > 3 &&
					strncasecmp(optarg, "hci", 3) == 0)
				index = atoi(optarg + 3);
			else
				index = atoi(optarg);
			break;
		case 'h':
		default:
			usage();
			return 0;
		}
	}

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

	mainloop_init();

	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 (argc > 0) {
		struct cmd_info *c;

		c = find_cmd(argv[0], all_cmd, NELEM(all_cmd));
		if (!c) {
			fprintf(stderr, "Unknown command: %s\n", argv[0]);
			mgmt_unref(mgmt);
			return EXIT_FAILURE;
		}

		c->func(mgmt, index, argc, argv);
	}

	register_mgmt_callbacks(mgmt, index);

	/* Interactive mode */
	if (!argc)
		input = setup_stdin();
	else
		input = NULL;

	if (input) {
		interactive = true;

		rl_attempted_completion_function = cmd_completion;

		rl_erase_empty_line = 1;
		rl_callback_handler_install(NULL, rl_handler);

		update_prompt(index);
		rl_redisplay();
	}

	mgmt_index = index;

	status = mainloop_run();

	if (input) {
		io_destroy(input);

		rl_message("");
		rl_callback_handler_remove();
	}

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

	return status;
}
