tools/btmgmt: Port to use bt_shell

This replaces the direct usage of readline with bt_shell.
diff --git a/tools/btmgmt.c b/tools/btmgmt.c
index 3911ba2..122c46d 100644
--- a/tools/btmgmt.c
+++ b/tools/btmgmt.c
@@ -40,9 +40,6 @@
 #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"
@@ -52,11 +49,11 @@
 #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"
+#include "src/shared/shell.h"
 
 #define SCAN_TYPE_BREDR (1 << BDADDR_BREDR)
 #define SCAN_TYPE_LE ((1 << BDADDR_LE_PUBLIC) | (1 << BDADDR_LE_RANDOM))
@@ -67,10 +64,6 @@
 
 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;
@@ -80,6 +73,7 @@
 	.index = MGMT_INDEX_NONE,
 };
 
+
 static int pending_index = 0;
 
 #ifndef MIN
@@ -88,7 +82,7 @@
 
 #define PROMPT_ON	COLOR_BLUE "[mgmt]" COLOR_OFF "# "
 
-static void set_index(char *arg)
+static void set_index(const char *arg)
 {
 	if (!arg || !strcmp(arg, "none") || !strcmp(arg, "any") ||
 						!strcmp(arg, "all"))
@@ -110,38 +104,15 @@
 		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();
+	bt_shell_set_prompt(str);
 }
 
 #define print(fmt, arg...) do { \
-	if (interactive) \
-		rl_printf(fmt "\n", ## arg); \
-	else \
-		printf(fmt "\n", ## arg); \
+		bt_shell_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); \
+		bt_shell_printf(COLOR_RED fmt "\n" COLOR_OFF, ## arg); \
 } while (0)
 
 static size_t hex2bin(const char *hexstr, uint8_t *buf, size_t buflen)
@@ -428,7 +399,7 @@
 					ev->discovering ? "on" : "off");
 
 	if (ev->discovering == 0 && discovery)
-		return noninteractive_quit(EXIT_SUCCESS);
+		return bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
 static void new_link_key(uint16_t index, uint16_t len, const void *param,
@@ -481,29 +452,6 @@
 					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)
 {
@@ -516,9 +464,6 @@
 		return;
 	}
 
-	if (!memcmp(&ev->addr, &prompt.addr, sizeof(ev->addr)))
-		release_prompt();
-
 	if (len < sizeof(*ev))
 		reason = MGMT_DEV_DISCONN_UNKNOWN;
 	else
@@ -557,9 +502,6 @@
 		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));
@@ -739,14 +681,13 @@
 	if (status != 0) {
 		error("PIN Code reply failed with status 0x%02x (%s)",
 						status, mgmt_errstr(status));
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_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,
+static int mgmt_pin_reply(uint16_t index, const struct mgmt_addr_info *addr,
 					const char *pin, size_t len)
 {
 	struct mgmt_cp_pin_code_reply cp;
@@ -756,8 +697,8 @@
 	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);
+	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,
@@ -766,14 +707,13 @@
 	if (status != 0) {
 		error("PIN Neg reply failed with status 0x%02x (%s)",
 						status, mgmt_errstr(status));
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_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)
+static int mgmt_pin_neg_reply(uint16_t index, const struct mgmt_addr_info *addr)
 {
 	struct mgmt_cp_pin_code_neg_reply cp;
 
@@ -790,14 +730,13 @@
 	if (status != 0) {
 		error("User Confirm reply failed. status 0x%02x (%s)",
 						status, mgmt_errstr(status));
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_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)
+static int mgmt_confirm_reply(uint16_t index, const struct mgmt_addr_info *addr)
 {
 	struct mgmt_cp_user_confirm_reply cp;
 
@@ -814,13 +753,13 @@
 	if (status != 0) {
 		error("Confirm Neg reply failed. status 0x%02x (%s)",
 						status, mgmt_errstr(status));
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	print("User Confirm Negative Reply successful");
 }
 
-static int mgmt_confirm_neg_reply(struct mgmt *mgmt, uint16_t index,
+static int mgmt_confirm_neg_reply(uint16_t index,
 					const struct mgmt_addr_info *addr)
 {
 	struct mgmt_cp_user_confirm_reply cp;
@@ -838,15 +777,14 @@
 	if (status != 0) {
 		error("User Passkey reply failed. status 0x%02x (%s)",
 						status, mgmt_errstr(status));
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_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)
+static int mgmt_passkey_reply(uint16_t index, const struct mgmt_addr_info *addr,
+						uint32_t passkey)
 {
 	struct mgmt_cp_user_passkey_reply cp;
 
@@ -864,13 +802,13 @@
 	if (status != 0) {
 		error("Passkey Neg reply failed. status 0x%02x (%s)",
 						status, mgmt_errstr(status));
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	print("User Passkey Negative Reply successful");
 }
 
-static int mgmt_passkey_neg_reply(struct mgmt *mgmt, uint16_t index,
+static int mgmt_passkey_neg_reply(uint16_t index,
 					const struct mgmt_addr_info *addr)
 {
 	struct mgmt_cp_user_passkey_reply cp;
@@ -882,85 +820,40 @@
 				sizeof(cp), &cp, passkey_neg_rsp, NULL, NULL);
 }
 
-static bool prompt_input(const char *input)
+static void prompt_input(const char *input, void *user_data)
 {
 	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);
+			mgmt_pin_reply(prompt.index, &prompt.addr, input, len);
 		else
-			mgmt_pin_neg_reply(mgmt, prompt.index, &prompt.addr);
+			mgmt_pin_neg_reply(prompt.index, &prompt.addr);
 		break;
 	case MGMT_EV_USER_PASSKEY_REQUEST:
 		if (strlen(input) > 0)
-			mgmt_passkey_reply(mgmt, prompt.index, &prompt.addr,
+			mgmt_passkey_reply(prompt.index, &prompt.addr,
 								atoi(input));
 		else
-			mgmt_passkey_neg_reply(mgmt, prompt.index,
+			mgmt_passkey_neg_reply(prompt.index,
 								&prompt.addr);
 		break;
 	case MGMT_EV_USER_CONFIRM_REQUEST:
 		if (input[0] == 'y' || input[0] == 'Y')
-			mgmt_confirm_reply(mgmt, prompt.index, &prompt.addr);
+			mgmt_confirm_reply(prompt.index, &prompt.addr);
 		else
-			mgmt_confirm_neg_reply(mgmt, prompt.index,
-								&prompt.addr);
+			mgmt_confirm_neg_reply(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];
+	char msg[256];
 	va_list ap;
 	int off;
 
@@ -975,18 +868,7 @@
 	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);
+	bt_shell_prompt_input("", msg, prompt_input, NULL);
 }
 
 static void request_pin(uint16_t index, uint16_t len, const void *param,
@@ -1137,18 +1019,15 @@
 						get_le16(&rp->revision));
 
 done:
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
-static void cmd_usage(char *cmd);
-
-static void cmd_version(struct mgmt *mgmt, uint16_t index, int argc,
-								char **argv)
+static void cmd_version(int argc, char **argv)
 {
 	if (mgmt_send(mgmt, MGMT_OP_READ_VERSION, MGMT_INDEX_NONE,
 				0, NULL, version_rsp, NULL, NULL) == 0) {
 		error("Unable to send read_version cmd");
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -1199,16 +1078,16 @@
 	}
 
 done:
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
-static void cmd_commands(struct mgmt *mgmt, uint16_t index, int argc,
+static void cmd_commands(int argc,
 								char **argv)
 {
 	if (mgmt_send(mgmt, MGMT_OP_READ_COMMANDS, MGMT_INDEX_NONE,
 				0, NULL, commands_rsp, NULL, NULL) == 0) {
 		error("Unable to send read_commands cmd");
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -1246,7 +1125,7 @@
 	if (pending_index > 0)
 		return;
 
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
 static void unconf_index_rsp(uint8_t status, uint16_t len, const void *param,
@@ -1259,12 +1138,12 @@
 	if (status != 0) {
 		error("Reading index list failed with status 0x%02x (%s)",
 						status, mgmt_errstr(status));
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	if (len < sizeof(*rp)) {
 		error("Too small index list reply (%u bytes)", len);
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	count = le16_to_cpu(rp->num_controllers);
@@ -1272,7 +1151,7 @@
 	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);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	print("Unconfigured index list with %u item%s",
@@ -1284,33 +1163,33 @@
 		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);
+			return bt_shell_noninteractive_quit(EXIT_FAILURE);
 		}
 
 		pending_index++;
 	}
 
 	if (!count)
-		noninteractive_quit(EXIT_SUCCESS);
+		bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
-static void cmd_config(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_config(int argc, char **argv)
 {
-	if (index == MGMT_INDEX_NONE) {
+	if (mgmt_index == MGMT_INDEX_NONE) {
 		if (!mgmt_send(mgmt, MGMT_OP_READ_UNCONF_INDEX_LIST,
 					MGMT_INDEX_NONE, 0, NULL,
 					unconf_index_rsp, mgmt, NULL)) {
 			error("Unable to send unconf_index_list cmd");
-			return noninteractive_quit(EXIT_FAILURE);
+			return bt_shell_noninteractive_quit(EXIT_FAILURE);
 		}
 
 		return;
 	}
 
-	if (!mgmt_send(mgmt, MGMT_OP_READ_CONFIG_INFO, index, 0, NULL,
+	if (!mgmt_send(mgmt, MGMT_OP_READ_CONFIG_INFO, mgmt_index, 0, NULL,
 				config_info_rsp, UINT_TO_PTR(index), NULL)) {
 		error("Unable to send read_config_info cmd");
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -1346,7 +1225,7 @@
 	if (pending_index > 0)
 		return;
 
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
 static void info_rsp(uint8_t status, uint16_t len, const void *param,
@@ -1400,7 +1279,7 @@
 	if (pending_index > 0)
 		return;
 
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
 static void ext_info_rsp(uint8_t status, uint16_t len, const void *param,
@@ -1450,7 +1329,7 @@
 	if (pending_index > 0)
 		return;
 
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
 static void index_rsp(uint8_t status, uint16_t len, const void *param,
@@ -1464,12 +1343,12 @@
 	if (status != 0) {
 		error("Reading index list failed with status 0x%02x (%s)",
 						status, mgmt_errstr(status));
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	if (len < sizeof(*rp)) {
 		error("Too small index list reply (%u bytes)", len);
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	count = le16_to_cpu(rp->num_controllers);
@@ -1477,7 +1356,7 @@
 	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);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	print("Index list with %u item%s", count, count != 1 ? "s" : "");
@@ -1488,33 +1367,33 @@
 		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);
+			return bt_shell_noninteractive_quit(EXIT_FAILURE);
 		}
 
 		pending_index++;
 	}
 
 	if (!count)
-		noninteractive_quit(EXIT_SUCCESS);
+		bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
-static void cmd_info(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_info(int argc, char **argv)
 {
-	if (index == MGMT_INDEX_NONE) {
+	if (mgmt_index == MGMT_INDEX_NONE) {
 		if (!mgmt_send(mgmt, MGMT_OP_READ_INDEX_LIST,
 					MGMT_INDEX_NONE, 0, NULL,
 					index_rsp, mgmt, NULL)) {
 			error("Unable to send index_list cmd");
-			return noninteractive_quit(EXIT_FAILURE);
+			return bt_shell_noninteractive_quit(EXIT_FAILURE);
 		}
 
 		return;
 	}
 
-	if (!mgmt_send(mgmt, MGMT_OP_READ_INFO, index, 0, NULL, info_rsp,
-						UINT_TO_PTR(index), NULL)) {
+	if (!mgmt_send(mgmt, MGMT_OP_READ_INFO, mgmt_index, 0, NULL, info_rsp,
+					UINT_TO_PTR(mgmt_index), NULL)) {
 		error("Unable to send read_info cmd");
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -1528,12 +1407,12 @@
 	if (status != 0) {
 		error("Reading ext index list failed with status 0x%02x (%s)",
 						status, mgmt_errstr(status));
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	if (len < sizeof(*rp)) {
 		error("Too small ext index list reply (%u bytes)", len);
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	count = get_le16(&rp->num_controllers);
@@ -1541,7 +1420,7 @@
 	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);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	print("Extended index list with %u item%s",
@@ -1561,7 +1440,7 @@
 						index, 0, NULL, ext_info_rsp,
 						UINT_TO_PTR(index), NULL)) {
 				error("Unable to send read_ext_info cmd");
-				return noninteractive_quit(EXIT_FAILURE);
+				return bt_shell_noninteractive_quit(EXIT_FAILURE);
 			}
 			pending_index++;
 			break;
@@ -1572,7 +1451,7 @@
 						index, 0, NULL, config_info_rsp,
 						UINT_TO_PTR(index), NULL)) {
 				error("Unable to send read_config cmd");
-				return noninteractive_quit(EXIT_FAILURE);
+				return bt_shell_noninteractive_quit(EXIT_FAILURE);
 			}
 			pending_index++;
 			break;
@@ -1589,17 +1468,17 @@
 	print("");
 
 	if (!count)
-		noninteractive_quit(EXIT_SUCCESS);
+		bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
-static void cmd_extinfo(struct mgmt *mgmt, uint16_t index,
+static void cmd_extinfo(
 						int argc, char **argv)
 {
 	if (!mgmt_send(mgmt, MGMT_OP_READ_EXT_INDEX_LIST,
 				MGMT_INDEX_NONE, 0, NULL,
 				ext_index_rsp, UINT_TO_PTR(index), NULL)) {
 		error("Unable to send ext_index_list cmd");
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -1610,7 +1489,7 @@
 
 	print("Successfully enabled controller with index %u", index);
 
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
 static void auto_power_info_rsp(uint8_t status, uint16_t len,
@@ -1624,7 +1503,7 @@
 	if (status) {
 		error("Reading info failed with status 0x%02x (%s)",
 						status, mgmt_errstr(status));
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	supported_settings = le32_to_cpu(rp->supported_settings);
@@ -1653,13 +1532,13 @@
 							NULL, NULL, NULL);
 
 	if (current_settings & MGMT_SETTING_POWERED)
-		return noninteractive_quit(EXIT_SUCCESS);
+		return bt_shell_noninteractive_quit(EXIT_SUCCESS);
 
 	if (!mgmt_send(mgmt, MGMT_OP_SET_POWERED, index, sizeof(val), &val,
 						auto_power_enable_rsp,
 						UINT_TO_PTR(index), NULL)) {
 		error("Unable to send set powerd cmd");
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -1677,7 +1556,7 @@
 						auto_power_info_rsp,
 						UINT_TO_PTR(index), NULL)) {
 		error("Unable to send read info cmd");
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -1692,7 +1571,7 @@
 	if (status) {
 		error("Reading index list failed with status 0x%02x (%s)",
 						status, mgmt_errstr(status));
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	count = le16_to_cpu(rp->num_controllers);
@@ -1716,13 +1595,15 @@
 						auto_power_info_rsp,
 						UINT_TO_PTR(index), NULL)) {
 		error("Unable to send read info cmd");
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
-static void cmd_auto_power(struct mgmt *mgmt, uint16_t index,
-						int argc, char **argv)
+static void cmd_auto_power(int argc, char **argv)
 {
+	int index;
+
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
@@ -1730,7 +1611,7 @@
 						auto_power_index_rsp,
 						UINT_TO_PTR(index), NULL)) {
 		error("Unable to send read index list cmd");
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -1795,16 +1676,11 @@
 						settings2str(get_le32(rp)));
 
 done:
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
 static bool parse_setting(int argc, char **argv, uint8_t *val)
 {
-	if (argc < 2) {
-		cmd_usage(argv[0]);
-		return false;
-	}
-
 	if (strcasecmp(argv[1], "on") == 0 || strcasecmp(argv[1], "yes") == 0)
 		*val = 1;
 	else if (strcasecmp(argv[1], "off") == 0)
@@ -1814,37 +1690,33 @@
 	return true;
 }
 
-static void cmd_setting(struct mgmt *mgmt, uint16_t index, uint16_t op,
-							int argc, char **argv)
+static void cmd_setting(uint16_t op, int argc, char **argv)
 {
+	int index;
 	uint8_t val;
 
 	if (parse_setting(argc, argv, &val) == false)
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
 	if (send_cmd(mgmt, op, index, sizeof(val), &val, setting_rsp) == 0) {
 		error("Unable to send %s cmd", mgmt_opstr(op));
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
-static void cmd_power(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_power(int argc, char **argv)
 {
-	cmd_setting(mgmt, index, MGMT_OP_SET_POWERED, argc, argv);
+	cmd_setting(MGMT_OP_SET_POWERED, argc, argv);
 }
 
-static void cmd_discov(struct mgmt *mgmt, uint16_t index, int argc,
-								char **argv)
+static void cmd_discov(int argc, char **argv)
 {
 	struct mgmt_cp_set_discoverable cp;
-
-	if (argc < 2) {
-		cmd_usage(argv[0]);
-		return noninteractive_quit(EXIT_FAILURE);
-	}
+	uint16_t index;
 
 	memset(&cp, 0, sizeof(cp));
 
@@ -1860,53 +1732,46 @@
 	if (argc > 2)
 		cp.timeout = htobs(atoi(argv[2]));
 
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
 	if (send_cmd(mgmt, MGMT_OP_SET_DISCOVERABLE, index, sizeof(cp), &cp,
 							setting_rsp) == 0) {
 		error("Unable to send set_discoverable cmd");
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
-static void cmd_connectable(struct mgmt *mgmt, uint16_t index, int argc,
-								char **argv)
+static void cmd_connectable(int argc, char **argv)
 {
-	cmd_setting(mgmt, index, MGMT_OP_SET_CONNECTABLE, argc, argv);
+	cmd_setting(MGMT_OP_SET_CONNECTABLE, argc, argv);
 }
 
-static void cmd_fast_conn(struct mgmt *mgmt, uint16_t index, int argc,
-								char **argv)
+static void cmd_fast_conn(int argc, char **argv)
 {
-	cmd_setting(mgmt, index, MGMT_OP_SET_FAST_CONNECTABLE, argc, argv);
+	cmd_setting(MGMT_OP_SET_FAST_CONNECTABLE, argc, argv);
 }
 
-static void cmd_bondable(struct mgmt *mgmt, uint16_t index, int argc,
-								char **argv)
+static void cmd_bondable(int argc, char **argv)
 {
-	cmd_setting(mgmt, index, MGMT_OP_SET_BONDABLE, argc, argv);
+	cmd_setting(MGMT_OP_SET_BONDABLE, argc, argv);
 }
 
-static void cmd_linksec(struct mgmt *mgmt, uint16_t index, int argc,
-								char **argv)
+static void cmd_linksec(int argc, char **argv)
 {
-	cmd_setting(mgmt, index, MGMT_OP_SET_LINK_SECURITY, argc, argv);
+	cmd_setting(MGMT_OP_SET_LINK_SECURITY, argc, argv);
 }
 
-static void cmd_ssp(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_ssp(int argc, char **argv)
 {
-	cmd_setting(mgmt, index, MGMT_OP_SET_SSP, argc, argv);
+	cmd_setting(MGMT_OP_SET_SSP, argc, argv);
 }
 
-static void cmd_sc(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_sc(int argc, char **argv)
 {
 	uint8_t val;
-
-	if (argc < 2) {
-		cmd_usage(argv[0]);
-		return noninteractive_quit(EXIT_FAILURE);
-	}
+	uint16_t index;
 
 	if (strcasecmp(argv[1], "on") == 0 || strcasecmp(argv[1], "yes") == 0)
 		val = 1;
@@ -1917,45 +1782,46 @@
 	else
 		val = atoi(argv[1]);
 
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
 	if (send_cmd(mgmt, MGMT_OP_SET_SECURE_CONN, index,
 					sizeof(val), &val, setting_rsp) == 0) {
 		error("Unable to send set_secure_conn cmd");
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
-static void cmd_hs(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_hs(int argc, char **argv)
 {
-	cmd_setting(mgmt, index, MGMT_OP_SET_HS, argc, argv);
+	cmd_setting(MGMT_OP_SET_HS, argc, argv);
 }
 
-static void cmd_le(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_le(int argc, char **argv)
 {
-	cmd_setting(mgmt, index, MGMT_OP_SET_LE, argc, argv);
+	cmd_setting(MGMT_OP_SET_LE, argc, argv);
 }
 
-static void cmd_advertising(struct mgmt *mgmt, uint16_t index, int argc,
-								char **argv)
+static void cmd_advertising(int argc, char **argv)
 {
-	cmd_setting(mgmt, index, MGMT_OP_SET_ADVERTISING, argc, argv);
+	cmd_setting(MGMT_OP_SET_ADVERTISING, argc, argv);
 }
 
-static void cmd_bredr(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_bredr(int argc, char **argv)
 {
-	cmd_setting(mgmt, index, MGMT_OP_SET_BREDR, argc, argv);
+	cmd_setting(MGMT_OP_SET_BREDR, argc, argv);
 }
 
-static void cmd_privacy(struct mgmt *mgmt, uint16_t index, int argc,
-								char **argv)
+static void cmd_privacy(int argc, char **argv)
 {
 	struct mgmt_cp_set_privacy cp;
+	uint16_t index;
 
 	if (parse_setting(argc, argv, &cp.privacy) == false)
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
@@ -1963,7 +1829,7 @@
 		if (hex2bin(argv[2], cp.irk,
 					sizeof(cp.irk)) != sizeof(cp.irk)) {
 			error("Invalid key format");
-			return noninteractive_quit(EXIT_FAILURE);
+			return bt_shell_noninteractive_quit(EXIT_FAILURE);
 		}
 	} else {
 		int fd;
@@ -1971,13 +1837,13 @@
 		fd = open("/dev/urandom", O_RDONLY);
 		if (fd < 0) {
 			error("open(/dev/urandom): %s", strerror(errno));
-			return noninteractive_quit(EXIT_FAILURE);
+			return bt_shell_noninteractive_quit(EXIT_FAILURE);
 		}
 
 		if (read(fd, cp.irk, sizeof(cp.irk)) != sizeof(cp.irk)) {
 			error("Reading from urandom failed");
 			close(fd);
-			return noninteractive_quit(EXIT_FAILURE);
+			return bt_shell_noninteractive_quit(EXIT_FAILURE);
 		}
 
 		close(fd);
@@ -1986,7 +1852,7 @@
 	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);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -1998,39 +1864,36 @@
 	if (len == 0 && status != 0) {
 		error("%s failed, status 0x%02x (%s)",
 				mgmt_opstr(op), status, mgmt_errstr(status));
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	if (len != sizeof(*rp)) {
 		error("Unexpected %s len %u", mgmt_opstr(op), len);
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	print("%s succeeded. Class 0x%02x%02x%02x", mgmt_opstr(op),
 		rp->dev_class[2], rp->dev_class[1], rp->dev_class[0]);
 
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
-static void cmd_class(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_class(int argc, char **argv)
 {
 	uint8_t class[2];
-
-	if (argc < 3) {
-		cmd_usage(argv[0]);
-		return noninteractive_quit(EXIT_FAILURE);
-	}
+	uint16_t index;
 
 	class[0] = atoi(argv[1]);
 	class[1] = atoi(argv[2]);
 
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
 	if (send_cmd(mgmt, MGMT_OP_SET_DEV_CLASS, index, sizeof(class), class,
 							class_rsp) == 0) {
 		error("Unable to send set_dev_class cmd");
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -2043,12 +1906,12 @@
 	if (len == 0 && status != 0) {
 		error("Disconnect failed with status 0x%02x (%s)",
 						status, mgmt_errstr(status));
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	if (len != sizeof(*rp)) {
 		error("Invalid disconnect response length (%u)", len);
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	ba2str(&rp->addr.bdaddr, addr);
@@ -2059,7 +1922,7 @@
 		error("Disconnecting %s failed with status 0x%02x (%s)",
 				addr, status, mgmt_errstr(status));
 
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
 static struct option disconnect_options[] = {
@@ -2068,13 +1931,12 @@
 	{ 0, 0, 0, 0 }
 };
 
-static void cmd_disconnect(struct mgmt *mgmt, uint16_t index, int argc,
-								char **argv)
+static void cmd_disconnect(int argc, char **argv)
 {
 	struct mgmt_cp_disconnect cp;
 	uint8_t type = BDADDR_BREDR;
 	int opt;
-	char *cmd = argv[0];
+	uint16_t index;
 
 	while ((opt = getopt_long(argc, argv, "+t:h", disconnect_options,
 								NULL)) != -1) {
@@ -2083,13 +1945,13 @@
 			type = strtol(optarg, NULL, 0);
 			break;
 		case 'h':
-			cmd_usage(cmd);
+			bt_shell_usage();
 			optind = 0;
-			return noninteractive_quit(EXIT_SUCCESS);
+			return bt_shell_noninteractive_quit(EXIT_SUCCESS);
 		default:
-			cmd_usage(cmd);
+			bt_shell_usage();
 			optind = 0;
-			return noninteractive_quit(EXIT_FAILURE);
+			return bt_shell_noninteractive_quit(EXIT_FAILURE);
 		}
 	}
 
@@ -2097,11 +1959,7 @@
 	argv += optind;
 	optind = 0;
 
-	if (argc < 1) {
-		cmd_usage(cmd);
-		return noninteractive_quit(EXIT_FAILURE);
-	}
-
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
@@ -2112,7 +1970,7 @@
 	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);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -2124,14 +1982,14 @@
 
 	if (len < sizeof(*rp)) {
 		error("Too small (%u bytes) get_connections rsp", len);
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	count = get_le16(&rp->conn_count);
 	if (len != sizeof(*rp) + count * sizeof(struct mgmt_addr_info)) {
 		error("Invalid get_connections length (count=%u, len=%u)",
 								count, len);
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	for (i = 0; i < count; i++) {
@@ -2142,18 +2000,21 @@
 		print("%s type %s", addr, typestr(rp->addr[i].type));
 	}
 
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
-static void cmd_con(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_con(int argc, char **argv)
 {
+	uint16_t index;
+
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
 	if (mgmt_send(mgmt, MGMT_OP_GET_CONNECTIONS, index, 0, NULL,
 						con_rsp, NULL, NULL) == 0) {
 		error("Unable to send get_connections cmd");
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -2163,7 +2024,7 @@
 	if (status != 0) {
 		error("Start Service Discovery failed: status 0x%02x (%s)",
 						status, mgmt_errstr(status));
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	print("Service discovery started");
@@ -2191,8 +2052,7 @@
 
 #define MAX_UUIDS 4
 
-static void cmd_find_service(struct mgmt *mgmt, uint16_t index, int argc,
-			     char **argv)
+static void cmd_find_service(int argc, char **argv)
 {
 	struct mgmt_cp_start_service_discovery *cp;
 	uint8_t buf[sizeof(*cp) + 16 * MAX_UUIDS];
@@ -2203,19 +2063,15 @@
 	int8_t rssi;
 	uint16_t count;
 	int opt;
-	char *cmd = argv[0];
+	uint16_t index;
 
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
 	rssi = 127;
 	count = 0;
 
-	if (argc == 1) {
-		cmd_usage(cmd);
-		return noninteractive_quit(EXIT_FAILURE);
-	}
-
 	while ((opt = getopt_long(argc, argv, "+lbu:r:h",
 					find_service_options, NULL)) != -1) {
 		switch (opt) {
@@ -2231,13 +2087,13 @@
 			if (count == MAX_UUIDS) {
 				print("Max %u UUIDs supported", MAX_UUIDS);
 				optind = 0;
-				return noninteractive_quit(EXIT_FAILURE);
+				return bt_shell_noninteractive_quit(EXIT_FAILURE);
 			}
 
 			if (bt_string2uuid(&uuid, optarg) < 0) {
 				print("Invalid UUID: %s", optarg);
 				optind = 0;
-				return noninteractive_quit(EXIT_FAILURE);
+				return bt_shell_noninteractive_quit(EXIT_FAILURE);
 			}
 			cp = (void *) buf;
 			uuid_to_uuid128(&uuid128, &uuid);
@@ -2249,13 +2105,13 @@
 			rssi = atoi(optarg);
 			break;
 		case 'h':
-			cmd_usage(cmd);
+			bt_shell_usage();
 			optind = 0;
-			return noninteractive_quit(EXIT_SUCCESS);
+			return bt_shell_noninteractive_quit(EXIT_SUCCESS);
 		default:
-			cmd_usage(cmd);
+			bt_shell_usage();
 			optind = 0;
-			return noninteractive_quit(EXIT_FAILURE);
+			return bt_shell_noninteractive_quit(EXIT_FAILURE);
 		}
 	}
 
@@ -2263,11 +2119,6 @@
 	argv += optind;
 	optind = 0;
 
-	if (argc > 0) {
-		cmd_usage(cmd);
-		return noninteractive_quit(EXIT_FAILURE);
-	}
-
 	cp = (void *) buf;
 	cp->type = type;
 	cp->rssi = rssi;
@@ -2277,7 +2128,7 @@
 				sizeof(*cp) + count * 16, cp,
 				find_service_rsp, NULL, NULL) == 0) {
 		error("Unable to send start_service_discovery cmd");
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -2287,7 +2138,7 @@
 	if (status != 0) {
 		error("Unable to start discovery. status 0x%02x (%s)",
 						status, mgmt_errstr(status));
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	print("Discovery started");
@@ -2302,14 +2153,15 @@
 	{ 0, 0, 0, 0 }
 };
 
-static void cmd_find(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_find(int argc, char **argv)
 {
 	struct mgmt_cp_start_discovery cp;
 	uint8_t op = MGMT_OP_START_DISCOVERY;
 	uint8_t type = SCAN_TYPE_DUAL;
 	int opt;
-	char *cmd = argv[0];
+	uint16_t index;
 
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
@@ -2328,13 +2180,13 @@
 			op = MGMT_OP_START_LIMITED_DISCOVERY;
 			break;
 		case 'h':
-			cmd_usage(cmd);
+			bt_shell_usage();
 			optind = 0;
-			return noninteractive_quit(EXIT_SUCCESS);
+			return bt_shell_noninteractive_quit(EXIT_SUCCESS);
 		default:
-			cmd_usage(cmd);
+			bt_shell_usage();
 			optind = 0;
-			return noninteractive_quit(EXIT_FAILURE);
+			return bt_shell_noninteractive_quit(EXIT_FAILURE);
 		}
 	}
 
@@ -2348,7 +2200,7 @@
 	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);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -2358,13 +2210,13 @@
 	if (status != 0) {
 		error("Stop Discovery failed: status 0x%02x (%s)",
 						status, mgmt_errstr(status));
-		return noninteractive_quit(EXIT_SUCCESS);
+		return bt_shell_noninteractive_quit(EXIT_SUCCESS);
 	}
 
 	print("Discovery stopped");
 	discovery = false;
 
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
 static struct option stop_find_options[] = {
@@ -2374,14 +2226,14 @@
 	{ 0, 0, 0, 0 }
 };
 
-static void cmd_stop_find(struct mgmt *mgmt, uint16_t index, int argc,
-			  char **argv)
+static void cmd_stop_find(int argc, char **argv)
 {
 	struct mgmt_cp_stop_discovery cp;
 	uint8_t type = SCAN_TYPE_DUAL;
 	int opt;
-	char *cmd = argv[0];
+	uint16_t index;
 
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
@@ -2398,9 +2250,9 @@
 			break;
 		case 'h':
 		default:
-			cmd_usage(cmd);
+			bt_shell_usage();
 			optind = 0;
-			return noninteractive_quit(EXIT_SUCCESS);
+			return bt_shell_noninteractive_quit(EXIT_SUCCESS);
 		}
 	}
 
@@ -2414,7 +2266,7 @@
 	if (mgmt_send(mgmt, MGMT_OP_STOP_DISCOVERY, index, sizeof(cp), &cp,
 					     stop_find_rsp, NULL, NULL) == 0) {
 		error("Unable to send stop_discovery cmd");
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -2425,18 +2277,15 @@
 		error("Unable to set local name with status 0x%02x (%s)",
 						status, mgmt_errstr(status));
 
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
-static void cmd_name(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_name(int argc, char **argv)
 {
 	struct mgmt_cp_set_local_name cp;
+	uint16_t index;
 
-	if (argc < 2) {
-		cmd_usage(argv[0]);
-		return noninteractive_quit(EXIT_FAILURE);
-	}
-
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
@@ -2449,7 +2298,7 @@
 	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);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -2462,17 +2311,14 @@
 	if (len == 0 && status != 0) {
 		error("Pairing failed with status 0x%02x (%s)",
 						status, mgmt_errstr(status));
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	if (len != sizeof(*rp)) {
 		error("Unexpected pair_rsp len %u", len);
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
-	if (!memcmp(&rp->addr, &prompt.addr, sizeof(rp->addr)))
-		release_prompt();
-
 	ba2str(&rp->addr.bdaddr, addr);
 
 	if (status)
@@ -2482,7 +2328,7 @@
 	else
 		print("Paired with %s (%s)", addr, typestr(rp->addr.type));
 
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
 static struct option pair_options[] = {
@@ -2492,14 +2338,14 @@
 	{ 0, 0, 0, 0 }
 };
 
-static void cmd_pair(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_pair(int argc, char **argv)
 {
 	struct mgmt_cp_pair_device cp;
 	uint8_t cap = 0x01;
 	uint8_t type = BDADDR_BREDR;
 	char addr[18];
 	int opt;
-	char *cmd = argv[0];
+	uint16_t index;
 
 	while ((opt = getopt_long(argc, argv, "+c:t:h", pair_options,
 								NULL)) != -1) {
@@ -2511,13 +2357,13 @@
 			type = strtol(optarg, NULL, 0);
 			break;
 		case 'h':
-			cmd_usage(cmd);
+			bt_shell_usage();
 			optind = 0;
-			return noninteractive_quit(EXIT_SUCCESS);
+			return bt_shell_noninteractive_quit(EXIT_SUCCESS);
 		default:
-			cmd_usage(cmd);
+			bt_shell_usage();
 			optind = 0;
-			return noninteractive_quit(EXIT_FAILURE);
+			return bt_shell_noninteractive_quit(EXIT_FAILURE);
 		}
 	}
 
@@ -2526,10 +2372,11 @@
 	optind = 0;
 
 	if (argc < 1) {
-		cmd_usage(cmd);
-		return noninteractive_quit(EXIT_FAILURE);
+		bt_shell_usage();
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
@@ -2544,7 +2391,7 @@
 	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);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -2557,12 +2404,12 @@
 	if (len == 0 && status != 0) {
 		error("Cancel Pairing failed with 0x%02x (%s)",
 						status, mgmt_errstr(status));
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	if (len != sizeof(*rp)) {
 		error("Unexpected cancel_pair_rsp len %u", len);
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	ba2str(&rp->bdaddr, addr);
@@ -2574,7 +2421,7 @@
 	else
 		print("Pairing Cancelled with %s", addr);
 
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
 static struct option cancel_pair_options[] = {
@@ -2583,13 +2430,12 @@
 	{ 0, 0, 0, 0 }
 };
 
-static void cmd_cancel_pair(struct mgmt *mgmt, uint16_t index, int argc,
-								char **argv)
+static void cmd_cancel_pair(int argc, char **argv)
 {
 	struct mgmt_addr_info cp;
 	uint8_t type = BDADDR_BREDR;
 	int opt;
-	char *cmd = argv[0];
+	uint16_t index;
 
 	while ((opt = getopt_long(argc, argv, "+t:h", cancel_pair_options,
 								NULL)) != -1) {
@@ -2598,13 +2444,13 @@
 			type = strtol(optarg, NULL, 0);
 			break;
 		case 'h':
-			cmd_usage(cmd);
+			bt_shell_usage();
 			optind = 0;
-			return noninteractive_quit(EXIT_SUCCESS);
+			return bt_shell_noninteractive_quit(EXIT_SUCCESS);
 		default:
-			cmd_usage(cmd);
+			bt_shell_usage();
 			optind = 0;
-			return noninteractive_quit(EXIT_FAILURE);
+			return bt_shell_noninteractive_quit(EXIT_FAILURE);
 		}
 	}
 
@@ -2613,10 +2459,11 @@
 	optind = 0;
 
 	if (argc < 1) {
-		cmd_usage(cmd);
-		return noninteractive_quit(EXIT_FAILURE);
+		bt_shell_usage();
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
@@ -2627,7 +2474,7 @@
 	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);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -2640,12 +2487,12 @@
 	if (len == 0 && status != 0) {
 		error("Unpair device failed. status 0x%02x (%s)",
 						status, mgmt_errstr(status));
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	if (len != sizeof(*rp)) {
 		error("Unexpected unpair_device_rsp len %u", len);
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	ba2str(&rp->addr.bdaddr, addr);
@@ -2656,7 +2503,7 @@
 	else
 		print("%s unpaired", addr);
 
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
 static struct option unpair_options[] = {
@@ -2665,13 +2512,12 @@
 	{ 0, 0, 0, 0 }
 };
 
-static void cmd_unpair(struct mgmt *mgmt, uint16_t index, int argc,
-								char **argv)
+static void cmd_unpair(int argc, char **argv)
 {
 	struct mgmt_cp_unpair_device cp;
 	uint8_t type = BDADDR_BREDR;
 	int opt;
-	char *cmd = argv[0];
+	uint16_t index = mgmt_index;
 
 	while ((opt = getopt_long(argc, argv, "+t:h", unpair_options,
 								NULL)) != -1) {
@@ -2680,13 +2526,13 @@
 			type = strtol(optarg, NULL, 0);
 			break;
 		case 'h':
-			cmd_usage(cmd);
+			bt_shell_usage();
 			optind = 0;
-			return noninteractive_quit(EXIT_SUCCESS);
+			return bt_shell_noninteractive_quit(EXIT_SUCCESS);
 		default:
-			cmd_usage(cmd);
+			bt_shell_usage();
 			optind = 0;
-			return noninteractive_quit(EXIT_FAILURE);
+			return bt_shell_noninteractive_quit(EXIT_FAILURE);
 		}
 	}
 
@@ -2695,10 +2541,11 @@
 	optind = 0;
 
 	if (argc < 1) {
-		cmd_usage(cmd);
-		return noninteractive_quit(EXIT_FAILURE);
+		bt_shell_usage();
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
@@ -2710,7 +2557,7 @@
 	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);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -2723,13 +2570,15 @@
 	else
 		print("Keys successfully loaded");
 
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
-static void cmd_keys(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_keys(int argc, char **argv)
 {
 	struct mgmt_cp_load_link_keys cp;
+	uint16_t index;
 
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
@@ -2738,7 +2587,7 @@
 	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);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -2751,13 +2600,15 @@
 	else
 		print("Long term keys successfully loaded");
 
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
-static void cmd_ltks(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_ltks(int argc, char **argv)
 {
 	struct mgmt_cp_load_long_term_keys cp;
+	uint16_t index;
 
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
@@ -2766,7 +2617,7 @@
 	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);
+		return bt_shell_noninteractive_quit(EXIT_SUCCESS);
 	}
 }
 
@@ -2779,7 +2630,7 @@
 	else
 		print("Identity Resolving Keys successfully loaded");
 
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
 static struct option irks_options[] = {
@@ -2791,15 +2642,16 @@
 
 #define MAX_IRKS 4
 
-static void cmd_irks(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_irks(int argc, char **argv)
 {
 	struct mgmt_cp_load_irks *cp;
 	uint8_t buf[sizeof(*cp) + 23 * MAX_IRKS];
 	uint16_t count, local_index;
 	char path[PATH_MAX];
 	int opt;
-	char *cmd = argv[0];
+	uint16_t index;
 
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
@@ -2813,7 +2665,7 @@
 			if (count >= MAX_IRKS) {
 				error("Number of IRKs exceeded");
 				optind = 0;
-				return noninteractive_quit(EXIT_FAILURE);
+				return bt_shell_noninteractive_quit(EXIT_FAILURE);
 			}
 			if (strlen(optarg) > 3 &&
 					strncasecmp(optarg, "hci", 3) == 0)
@@ -2826,7 +2678,7 @@
 			if (!load_identity(path, &cp->irks[count])) {
 				error("Unable to load identity");
 				optind = 0;
-				return noninteractive_quit(EXIT_FAILURE);
+				return bt_shell_noninteractive_quit(EXIT_FAILURE);
 			}
 			count++;
 			break;
@@ -2834,23 +2686,23 @@
 			if (count >= MAX_IRKS) {
 				error("Number of IRKs exceeded");
 				optind = 0;
-				return noninteractive_quit(EXIT_FAILURE);
+				return bt_shell_noninteractive_quit(EXIT_FAILURE);
 			}
 			if (!load_identity(optarg, &cp->irks[count])) {
 				error("Unable to load identities");
 				optind = 0;
-				return noninteractive_quit(EXIT_FAILURE);
+				return bt_shell_noninteractive_quit(EXIT_FAILURE);
 			}
 			count++;
 			break;
 		case 'h':
-			cmd_usage(cmd);
+			bt_shell_usage();
 			optind = 0;
-			return noninteractive_quit(EXIT_SUCCESS);
+			return bt_shell_noninteractive_quit(EXIT_SUCCESS);
 		default:
-			cmd_usage(cmd);
+			bt_shell_usage();
 			optind = 0;
-			return noninteractive_quit(EXIT_FAILURE);
+			return bt_shell_noninteractive_quit(EXIT_FAILURE);
 		}
 	}
 
@@ -2858,18 +2710,13 @@
 	argv += optind;
 	optind = 0;
 
-	if (argc > 0) {
-		cmd_usage(cmd);
-		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);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -2882,12 +2729,12 @@
 	if (len == 0 && status != 0) {
 		error("%s failed, status 0x%02x (%s)",
 				mgmt_opstr(op), status, mgmt_errstr(status));
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	if (len != sizeof(*rp)) {
 		error("Unexpected %s len %u", mgmt_opstr(op), len);
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	ba2str(&rp->bdaddr, addr);
@@ -2899,7 +2746,7 @@
 	else
 		print("%s %s succeeded", mgmt_opstr(op), addr);
 
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
 static struct option block_options[] = {
@@ -2908,12 +2755,12 @@
 	{ 0, 0, 0, 0 }
 };
 
-static void cmd_block(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_block(int argc, char **argv)
 {
 	struct mgmt_cp_block_device cp;
 	uint8_t type = BDADDR_BREDR;
 	int opt;
-	char *cmd = argv[0];
+	uint16_t index;
 
 	while ((opt = getopt_long(argc, argv, "+t:h", block_options,
 							NULL)) != -1) {
@@ -2922,13 +2769,13 @@
 			type = strtol(optarg, NULL, 0);
 			break;
 		case 'h':
-			cmd_usage(cmd);
+			bt_shell_usage();
 			optind = 0;
-			return noninteractive_quit(EXIT_SUCCESS);
+			return bt_shell_noninteractive_quit(EXIT_SUCCESS);
 		default:
-			cmd_usage(cmd);
+			bt_shell_usage();
 			optind = 0;
-			return noninteractive_quit(EXIT_FAILURE);
+			return bt_shell_noninteractive_quit(EXIT_FAILURE);
 		}
 	}
 
@@ -2937,10 +2784,11 @@
 	optind = 0;
 
 	if (argc < 1) {
-		cmd_usage(cmd);
-		return noninteractive_quit(EXIT_FAILURE);
+		bt_shell_usage();
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
@@ -2951,17 +2799,16 @@
 	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);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
-static void cmd_unblock(struct mgmt *mgmt, uint16_t index, int argc,
-								char **argv)
+static void cmd_unblock(int argc, char **argv)
 {
 	struct mgmt_cp_unblock_device cp;
 	uint8_t type = BDADDR_BREDR;
 	int opt;
-	char *cmd = argv[0];
+	uint16_t index;
 
 	while ((opt = getopt_long(argc, argv, "+t:h", block_options,
 							NULL)) != -1) {
@@ -2970,13 +2817,13 @@
 			type = strtol(optarg, NULL, 0);
 			break;
 		case 'h':
-			cmd_usage(cmd);
+			bt_shell_usage();
 			optind = 0;
-			return noninteractive_quit(EXIT_SUCCESS);
+			return bt_shell_noninteractive_quit(EXIT_SUCCESS);
 		default:
-			cmd_usage(cmd);
+			bt_shell_usage();
 			optind = 0;
-			return noninteractive_quit(EXIT_FAILURE);
+			return bt_shell_noninteractive_quit(EXIT_FAILURE);
 		}
 	}
 
@@ -2985,10 +2832,11 @@
 	optind = 0;
 
 	if (argc < 1) {
-		cmd_usage(cmd);
-		return noninteractive_quit(EXIT_FAILURE);
+		bt_shell_usage();
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
@@ -2999,28 +2847,29 @@
 	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);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
-static void cmd_add_uuid(struct mgmt *mgmt, uint16_t index, int argc,
-							char **argv)
+static void cmd_add_uuid(int argc, char **argv)
 {
 	struct mgmt_cp_add_uuid cp;
 	uint128_t uint128;
 	uuid_t uuid, uuid128;
+	uint16_t index;
 
 	if (argc < 3) {
 		print("UUID and service hint needed");
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
 	if (bt_string2uuid(&uuid, argv[1]) < 0) {
 		print("Invalid UUID: %s", argv[1]);
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	memset(&cp, 0, sizeof(cp));
@@ -3034,28 +2883,29 @@
 	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);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
-static void cmd_remove_uuid(struct mgmt *mgmt, uint16_t index, int argc,
-								char **argv)
+static void cmd_remove_uuid(int argc, char **argv)
 {
 	struct mgmt_cp_remove_uuid cp;
 	uint128_t uint128;
 	uuid_t uuid, uuid128;
+	uint16_t index;
 
 	if (argc < 2) {
 		print("UUID needed");
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
 	if (bt_string2uuid(&uuid, argv[1]) < 0) {
 		print("Invalid UUID: %s", argv[1]);
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	memset(&cp, 0, sizeof(cp));
@@ -3067,17 +2917,16 @@
 	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);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
-static void cmd_clr_uuids(struct mgmt *mgmt, uint16_t index, int argc,
-								char **argv)
+static void cmd_clr_uuids(int argc, char **argv)
 {
 	char *uuid_any = "00000000-0000-0000-0000-000000000000";
 	char *rm_argv[] = { "rm-uuid", uuid_any, NULL };
 
-	cmd_remove_uuid(mgmt, index, 2, rm_argv);
+	cmd_remove_uuid(2, rm_argv);
 }
 
 static void local_oob_rsp(uint8_t status, uint16_t len, const void *param,
@@ -3089,12 +2938,12 @@
 	if (status != 0) {
 		error("Read Local OOB Data failed with status 0x%02x (%s)",
 						status, mgmt_errstr(status));
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	if (len < sizeof(*rp)) {
 		error("Too small (%u bytes) read_local_oob rsp", len);
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	bin2hex(rp->hash192, 16, str, sizeof(str));
@@ -3104,7 +2953,7 @@
 	print("Randomizer R with P-192: %s", str);
 
 	if (len < sizeof(*rp))
-		return noninteractive_quit(EXIT_SUCCESS);
+		return bt_shell_noninteractive_quit(EXIT_SUCCESS);
 
 	bin2hex(rp->hash256, 16, str, sizeof(str));
 	print("Hash C from P-256: %s", str);
@@ -3112,19 +2961,21 @@
 	bin2hex(rp->rand256, 16, str, sizeof(str));
 	print("Randomizer R with P-256: %s", str);
 
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
-static void cmd_local_oob(struct mgmt *mgmt, uint16_t index,
-						int argc, char **argv)
+static void cmd_local_oob(int argc, char **argv)
 {
+	uint16_t index;
+
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
 	if (mgmt_send(mgmt, MGMT_OP_READ_LOCAL_OOB_DATA, index, 0, NULL,
 					local_oob_rsp, NULL, NULL) == 0) {
 		error("Unable to send read_local_oob cmd");
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -3155,12 +3006,11 @@
 	{ 0, 0, 0, 0 }
 };
 
-static void cmd_remote_oob(struct mgmt *mgmt, uint16_t index,
-						int argc, char **argv)
+static void cmd_remote_oob(int argc, char **argv)
 {
 	struct mgmt_cp_add_remote_oob_data cp;
 	int opt;
-	char *cmd = argv[0];
+	uint16_t index;
 
 	memset(&cp, 0, sizeof(cp));
 	cp.addr.type = BDADDR_BREDR;
@@ -3184,9 +3034,9 @@
 			hex2bin(optarg, cp.hash256, 16);
 			break;
 		default:
-			cmd_usage(cmd);
+			bt_shell_usage();
 			optind = 0;
-			return noninteractive_quit(EXIT_FAILURE);
+			return bt_shell_noninteractive_quit(EXIT_FAILURE);
 		}
 	}
 
@@ -3195,10 +3045,11 @@
 	optind = 0;
 
 	if (argc < 1) {
-		cmd_usage(cmd);
-		return noninteractive_quit(EXIT_FAILURE);
+		bt_shell_usage();
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
@@ -3210,7 +3061,7 @@
 				sizeof(cp), &cp, remote_oob_rsp,
 				NULL, NULL) == 0) {
 		error("Unable to send add_remote_oob cmd");
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -3223,25 +3074,15 @@
 	else
 		print("Device ID successfully set");
 
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
-static void did_usage(void)
-{
-	cmd_usage("did");
-	print("       possible source values: bluetooth, usb");
-}
-
-static void cmd_did(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_did(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);
-	}
+	uint16_t index;
 
 	result = sscanf(argv[1], "bluetooth:%4hx:%4hx:%4hx", &vendor, &product,
 								&version);
@@ -3257,10 +3098,9 @@
 		goto done;
 	}
 
-	did_usage();
-	return noninteractive_quit(EXIT_FAILURE);
-
+	return;
 done:
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
@@ -3272,7 +3112,7 @@
 	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);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -3285,19 +3125,15 @@
 	else
 		print("Static address successfully set");
 
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
-static void cmd_static_addr(struct mgmt *mgmt, uint16_t index,
-							int argc, char **argv)
+static void cmd_static_addr(int argc, char **argv)
 {
 	struct mgmt_cp_set_static_address cp;
+	uint16_t index;
 
-	if (argc < 2) {
-		cmd_usage(argv[0]);
-		return noninteractive_quit(EXIT_FAILURE);
-	}
-
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
@@ -3306,7 +3142,7 @@
 	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);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -3318,31 +3154,27 @@
 	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);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	if (len < sizeof(*rp)) {
 		error("Too small %s response (%u bytes)",
 							mgmt_opstr(op), len);
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	print("hci%u %s complete, options: %s", id, mgmt_opstr(op),
 						options2str(get_le32(rp)));
 
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
-static void cmd_public_addr(struct mgmt *mgmt, uint16_t index,
-						int argc, char **argv)
+static void cmd_public_addr(int argc, char **argv)
 {
 	struct mgmt_cp_set_public_address cp;
+	uint16_t index;
 
-	if (argc < 2) {
-		cmd_usage(argv[0]);
-		return noninteractive_quit(EXIT_FAILURE);
-	}
-
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
@@ -3351,32 +3183,32 @@
 	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);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
-static void cmd_ext_config(struct mgmt *mgmt, uint16_t index,
-						int argc, char **argv)
+static void cmd_ext_config(int argc, char **argv)
 {
 	struct mgmt_cp_set_external_config cp;
+	uint16_t index;
 
 	if (parse_setting(argc, argv, &cp.config) == false)
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
 	if (send_cmd(mgmt, MGMT_OP_SET_EXTERNAL_CONFIG, index, sizeof(cp), &cp,
 							options_rsp) == 0) {
 		error("Unable to send Set External Config cmd");
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
-static void cmd_debug_keys(struct mgmt *mgmt, uint16_t index,
-						int argc, char **argv)
+static void cmd_debug_keys(int argc, char **argv)
 {
-	cmd_setting(mgmt, index, MGMT_OP_SET_DEBUG_KEYS, argc, argv);
+	cmd_setting(MGMT_OP_SET_DEBUG_KEYS, argc, argv);
 }
 
 static void conn_info_rsp(uint8_t status, uint16_t len, const void *param,
@@ -3387,12 +3219,12 @@
 	if (len == 0 && status != 0) {
 		error("Get Conn Info failed, status 0x%02x (%s)",
 						status, mgmt_errstr(status));
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	if (len < sizeof(*rp)) {
 		error("Unexpected Get Conn Info len %u", len);
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	ba2str(&rp->addr.bdaddr, addr);
@@ -3408,22 +3240,21 @@
 				rp->rssi, rp->tx_power, rp->max_tx_power);
 	}
 
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
 static struct option conn_info_options[] = {
-	{ "help",	0, 0, 'h' },
-	{ "type",	1, 0, 't' },
+	{ "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)
+static void cmd_conn_info(int argc, char **argv)
 {
 	struct mgmt_cp_get_conn_info cp;
 	uint8_t type = BDADDR_BREDR;
 	int opt;
-	char *cmd = argv[0];
+	uint16_t index;
 
 	while ((opt = getopt_long(argc, argv, "+t:h", conn_info_options,
 								NULL)) != -1) {
@@ -3432,13 +3263,13 @@
 			type = strtol(optarg, NULL, 0);
 			break;
 		case 'h':
-			cmd_usage(cmd);
+			bt_shell_usage();
 			optind = 0;
-			return noninteractive_quit(EXIT_SUCCESS);
+			return bt_shell_noninteractive_quit(EXIT_SUCCESS);
 		default:
-			cmd_usage(cmd);
+			bt_shell_usage();
 			optind = 0;
-			return noninteractive_quit(EXIT_FAILURE);
+			return bt_shell_noninteractive_quit(EXIT_FAILURE);
 		}
 	}
 
@@ -3447,10 +3278,11 @@
 	optind = 0;
 
 	if (argc < 1) {
-		cmd_usage(cmd);
-		return noninteractive_quit(EXIT_FAILURE);
+		bt_shell_usage();
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
@@ -3461,7 +3293,7 @@
 	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);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -3474,20 +3306,16 @@
 	else
 		print("IO Capabilities successfully set");
 
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
-static void cmd_io_cap(struct mgmt *mgmt, uint16_t index,
-						int argc, char **argv)
+static void cmd_io_cap(int argc, char **argv)
 {
 	struct mgmt_cp_set_io_capability cp;
 	uint8_t cap;
+	uint16_t index;
 
-	if (argc < 2) {
-		cmd_usage(argv[0]);
-		return noninteractive_quit(EXIT_FAILURE);
-	}
-
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
@@ -3498,7 +3326,7 @@
 	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);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -3511,19 +3339,15 @@
 	else
 		print("Scan parameters successfully set");
 
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
-static void cmd_scan_params(struct mgmt *mgmt, uint16_t index,
-							int argc, char **argv)
+static void cmd_scan_params(int argc, char **argv)
 {
 	struct mgmt_cp_set_scan_params cp;
+	uint16_t index;
 
-	if (argc < 3) {
-		cmd_usage(argv[0]);
-		return noninteractive_quit(EXIT_FAILURE);
-	}
-
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
@@ -3533,7 +3357,7 @@
 	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);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -3544,27 +3368,28 @@
 
 	if (len < sizeof(*rp)) {
 		error("Unexpected Get Clock Info len %u", len);
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_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);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	print("Local Clock:   %u", le32_to_cpu(rp->local_clock));
 	print("Piconet Clock: %u", le32_to_cpu(rp->piconet_clock));
 	print("Accurary:      %u", le16_to_cpu(rp->accuracy));
 
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
-static void cmd_clock_info(struct mgmt *mgmt, uint16_t index,
-							int argc, char **argv)
+static void cmd_clock_info(int argc, char **argv)
 {
 	struct mgmt_cp_get_clock_info cp;
+	uint16_t index;
 
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
@@ -3576,7 +3401,7 @@
 	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);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -3586,7 +3411,7 @@
 	if (status != 0)
 		error("Add device failed with status 0x%02x (%s)",
 						status, mgmt_errstr(status));
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
 static struct option add_device_options[] = {
@@ -3596,15 +3421,14 @@
 	{ 0, 0, 0, 0 }
 };
 
-static void cmd_add_device(struct mgmt *mgmt, uint16_t index,
-						int argc, char **argv)
+static void cmd_add_device(int argc, char **argv)
 {
 	struct mgmt_cp_add_device cp;
 	uint8_t action = 0x00;
 	uint8_t type = BDADDR_BREDR;
 	char addr[18];
 	int opt;
-	char *cmd = argv[0];
+	uint16_t index;
 
 	while ((opt = getopt_long(argc, argv, "+a:t:h", add_device_options,
 								NULL)) != -1) {
@@ -3616,13 +3440,13 @@
 			type = strtol(optarg, NULL, 0);
 			break;
 		case 'h':
-			cmd_usage(cmd);
+			bt_shell_usage();
 			optind = 0;
-			return noninteractive_quit(EXIT_SUCCESS);
+			return bt_shell_noninteractive_quit(EXIT_SUCCESS);
 		default:
-			cmd_usage(cmd);
+			bt_shell_usage();
 			optind = 0;
-			return noninteractive_quit(EXIT_FAILURE);
+			return bt_shell_noninteractive_quit(EXIT_FAILURE);
 		}
 	}
 
@@ -3631,10 +3455,11 @@
 	optind = 0;
 
 	if (argc < 1) {
-		cmd_usage(cmd);
-		return noninteractive_quit(EXIT_FAILURE);
+		bt_shell_usage();
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
@@ -3649,7 +3474,7 @@
 	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);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -3659,7 +3484,7 @@
 	if (status != 0)
 		error("Remove device failed with status 0x%02x (%s)",
 						status, mgmt_errstr(status));
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
 static struct option del_device_options[] = {
@@ -3668,14 +3493,13 @@
 	{ 0, 0, 0, 0 }
 };
 
-static void cmd_del_device(struct mgmt *mgmt, uint16_t index,
-						int argc, char **argv)
+static void cmd_del_device(int argc, char **argv)
 {
 	struct mgmt_cp_remove_device cp;
 	uint8_t type = BDADDR_BREDR;
 	char addr[18];
 	int opt;
-	char *cmd = argv[0];
+	uint16_t index;
 
 	while ((opt = getopt_long(argc, argv, "+t:h", del_device_options,
 								NULL)) != -1) {
@@ -3684,13 +3508,13 @@
 			type = strtol(optarg, NULL, 0);
 			break;
 		case 'h':
-			cmd_usage(cmd);
+			bt_shell_usage();
 			optind = 0;
-			return noninteractive_quit(EXIT_SUCCESS);
+			return bt_shell_noninteractive_quit(EXIT_SUCCESS);
 		default:
-			cmd_usage(cmd);
+			bt_shell_usage();
 			optind = 0;
-			return noninteractive_quit(EXIT_FAILURE);
+			return bt_shell_noninteractive_quit(EXIT_FAILURE);
 		}
 	}
 
@@ -3699,10 +3523,12 @@
 	optind = 0;
 
 	if (argc < 1) {
-		cmd_usage(cmd);
-		return noninteractive_quit(EXIT_FAILURE);
+		bt_shell_usage();
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
+
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
@@ -3716,17 +3542,16 @@
 	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);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
-static void cmd_clr_devices(struct mgmt *mgmt, uint16_t index,
-						int argc, char **argv)
+static void cmd_clr_devices(int argc, char **argv)
 {
 	char *bdaddr_any = "00:00:00:00:00:00";
 	char *rm_argv[] = { "del-device", bdaddr_any, NULL };
 
-	cmd_del_device(mgmt, index, 2, rm_argv);
+	cmd_del_device(2, rm_argv);
 }
 
 static void local_oob_ext_rsp(uint8_t status, uint16_t len, const void *param,
@@ -3738,31 +3563,32 @@
 	if (status != 0) {
 		error("Read Local OOB Ext Data failed with status 0x%02x (%s)",
 						status, mgmt_errstr(status));
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	if (len < sizeof(*rp)) {
 		error("Too small (%u bytes) read_local_oob_ext rsp", len);
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	eir_len = le16_to_cpu(rp->eir_len);
 	if (len != sizeof(*rp) + eir_len) {
 		error("local_oob_ext: expected %zu bytes, got %u bytes",
 						sizeof(*rp) + eir_len, len);
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	print_eir(rp->eir, eir_len);
 
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
-static void cmd_bredr_oob(struct mgmt *mgmt, uint16_t index,
-						int argc, char **argv)
+static void cmd_bredr_oob(int argc, char **argv)
 {
 	struct mgmt_cp_read_local_oob_ext_data cp;
+	uint16_t index;
 
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
@@ -3772,15 +3598,16 @@
 					index, sizeof(cp), &cp,
 					local_oob_ext_rsp, NULL, NULL)) {
 		error("Unable to send read_local_oob_ext cmd");
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
-static void cmd_le_oob(struct mgmt *mgmt, uint16_t index,
-						int argc, char **argv)
+static void cmd_le_oob(int argc, char **argv)
 {
 	struct mgmt_cp_read_local_oob_ext_data cp;
+	uint16_t index;
 
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
@@ -3790,7 +3617,7 @@
 					index, sizeof(cp), &cp,
 					local_oob_ext_rsp, NULL, NULL)) {
 		error("Unable to send read_local_oob_ext cmd");
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -3831,18 +3658,18 @@
 	if (status != 0) {
 		error("Reading adv features failed with status 0x%02x (%s)",
 						status, mgmt_errstr(status));
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	if (len < sizeof(*rp)) {
 		error("Too small adv features reply (%u bytes)", len);
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	if (len < sizeof(*rp) + rp->num_instances * sizeof(uint8_t)) {
 		error("Instances count (%u) doesn't match reply length (%u)",
 							rp->num_instances, len);
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	supported_flags = le32_to_cpu(rp->supported_flags);
@@ -3854,19 +3681,21 @@
 	print("Instances list with %u item%s", rp->num_instances,
 					rp->num_instances != 1 ? "s" : "");
 
-	return noninteractive_quit(EXIT_SUCCESS);
+	return bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
-static void cmd_advinfo(struct mgmt *mgmt, uint16_t index,
-						int argc, char **argv)
+static void cmd_advinfo(int argc, char **argv)
 {
+	uint16_t index;
+
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
 	if (!mgmt_send(mgmt, MGMT_OP_READ_ADV_FEATURES, index, 0, NULL,
 					adv_features_rsp, NULL, NULL)) {
 		error("Unable to send advertising features command");
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -3879,12 +3708,12 @@
 	if (status != 0) {
 		error("Reading adv size info failed with status 0x%02x (%s)",
 						status, mgmt_errstr(status));
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	if (len < sizeof(*rp)) {
 		error("Too small adv size info reply (%u bytes)", len);
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	flags = le32_to_cpu(rp->flags);
@@ -3893,19 +3722,19 @@
 	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);
+	return bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
 static void advsize_usage(void)
 {
-	cmd_usage("advsize");
+	bt_shell_usage();
 	print("Options:\n"
 		"\t -c, --connectable         \"connectable\" flag\n"
 		"\t -g, --general-discov      \"general-discoverable\" flag\n"
 		"\t -l, --limited-discov      \"limited-discoverable\" flag\n"
 		"\t -m, --managed-flags       \"managed-flags\" flag\n"
-		"\t -p, --tx-power            \"tx-power\" flag\n"\
-		"\t -a, --appearance          \"appearance\" flag\n"\
+		"\t -p, --tx-power            \"tx-power\" flag\n"
+		"\t -a, --appearance          \"appearance\" flag\n"
 		"\t -n, --local-name          \"local-name\" flag");
 }
 
@@ -3921,13 +3750,13 @@
 	{ 0, 0, 0, 0}
 };
 
-static void cmd_advsize(struct mgmt *mgmt, uint16_t index,
-						int argc, char **argv)
+static void cmd_advsize(int argc, char **argv)
 {
 	struct mgmt_cp_get_adv_size_info cp;
 	uint8_t instance;
 	uint32_t flags = 0;
 	int opt;
+	uint16_t index;
 
 	while ((opt = getopt_long(argc, argv, "+cglmphna",
 						advsize_options, NULL)) != -1) {
@@ -3956,7 +3785,7 @@
 		default:
 			advsize_usage();
 			optind = 0;
-			return noninteractive_quit(EXIT_FAILURE);
+			return bt_shell_noninteractive_quit(EXIT_FAILURE);
 		}
 	}
 
@@ -3966,11 +3795,12 @@
 
 	if (argc != 1) {
 		advsize_usage();
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	instance = strtol(argv[0], NULL, 0);
 
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
@@ -3982,7 +3812,7 @@
 	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);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
@@ -3994,22 +3824,22 @@
 	if (status != 0) {
 		error("Add Advertising failed with status 0x%02x (%s)",
 						status, mgmt_errstr(status));
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	if (len != sizeof(*rp)) {
 		error("Invalid Add Advertising response length (%u)", len);
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	print("Instance added: %u", rp->instance);
 
-	return noninteractive_quit(EXIT_SUCCESS);
+	return bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
 static void add_adv_usage(void)
 {
-	cmd_usage("add-adv");
+	bt_shell_usage();
 	print("Options:\n"
 		"\t -u, --uuid <uuid>         Service UUID\n"
 		"\t -d, --adv-data <data>     Advertising Data bytes\n"
@@ -4084,8 +3914,7 @@
 
 #define MAX_AD_UUID_BYTES 32
 
-static void cmd_add_adv(struct mgmt *mgmt, uint16_t index,
-							int argc, char **argv)
+static void cmd_add_adv(int argc, char **argv)
 {
 	struct mgmt_cp_add_advertising *cp = NULL;
 	int opt;
@@ -4101,6 +3930,7 @@
 	bool success = false;
 	bool quit = true;
 	uint32_t flags = 0;
+	uint16_t index;
 
 	while ((opt = getopt_long(argc, argv, "+u:d:s:t:D:cglmphna",
 						add_adv_options, NULL)) != -1) {
@@ -4211,6 +4041,7 @@
 
 	instance = strtol(argv[0], NULL, 0);
 
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
@@ -4249,7 +4080,7 @@
 	free(cp);
 
 	if (quit)
-		noninteractive_quit(success ? EXIT_SUCCESS : EXIT_FAILURE);
+		bt_shell_noninteractive_quit(success ? EXIT_SUCCESS : EXIT_FAILURE);
 }
 
 static void rm_adv_rsp(uint8_t status, uint16_t len, const void *param,
@@ -4260,31 +4091,28 @@
 	if (status != 0) {
 		error("Remove Advertising failed with status 0x%02x (%s)",
 						status, mgmt_errstr(status));
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	if (len != sizeof(*rp)) {
 		error("Invalid Remove Advertising response length (%u)", len);
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 
 	print("Instance removed: %u", rp->instance);
 
-	return noninteractive_quit(EXIT_SUCCESS);
+	return bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
-static void cmd_rm_adv(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_rm_adv(int argc, char **argv)
 {
 	struct mgmt_cp_remove_advertising cp;
 	uint8_t instance;
-
-	if (argc != 2) {
-		cmd_usage(argv[0]);
-		return noninteractive_quit(EXIT_FAILURE);
-	}
+	uint16_t index;
 
 	instance = strtol(argv[1], NULL, 0);
 
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
@@ -4295,16 +4123,16 @@
 	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);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
-static void cmd_clr_adv(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_clr_adv(int argc, char **argv)
 {
 	char *all_instances = "0";
 	char *rm_argv[] = { "rm-adv", all_instances, NULL };
 
-	cmd_rm_adv(mgmt, index, 2, rm_argv);
+	cmd_rm_adv(2, rm_argv);
 }
 
 static void appearance_rsp(uint8_t status, uint16_t len, const void *param,
@@ -4316,19 +4144,15 @@
 	else
 		print("Appearance successfully set");
 
-	noninteractive_quit(EXIT_SUCCESS);
+	bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
-static void cmd_appearance(struct mgmt *mgmt, uint16_t index, int argc,
-								char **argv)
+static void cmd_appearance(int argc, char **argv)
 {
 	struct mgmt_cp_set_appearance cp;
+	uint16_t index;
 
-	if (argc < 2) {
-		cmd_usage(argv[0]);
-		return noninteractive_quit(EXIT_FAILURE);
-	}
-
+	index = mgmt_index;
 	if (index == MGMT_INDEX_NONE)
 		index = 0;
 
@@ -4337,20 +4161,83 @@
 	if (mgmt_send(mgmt, MGMT_OP_SET_APPEARANCE, index, sizeof(cp), &cp,
 					appearance_rsp, NULL, NULL) == 0) {
 		error("Unable to send appearance cmd");
-		return noninteractive_quit(EXIT_FAILURE);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 	}
 }
 
-struct cmd_info {
-	char *cmd;
-	const char *arg;
-	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 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 struct cmd_info all_cmd[] = {
+static void cmd_select(int argc, char **argv)
+{
+	mgmt_cancel_all(mgmt);
+	mgmt_unregister_all(mgmt);
+
+	set_index(argv[1]);
+
+	register_mgmt_callbacks(mgmt, mgmt_index);
+
+	print("Selected index %u", mgmt_index);
+
+	update_prompt(mgmt_index);
+}
+
+static const struct bt_shell_menu main_menu = {
+	.name = "main",
+	.entries = {
+	{ "select",		"<index>",
+		cmd_select,		"Select a different index"	},
 	{ "version",		NULL,
 		cmd_version,		"Get the MGMT Version"		},
 	{ "commands",		NULL,
@@ -4473,333 +4360,9 @@
 		cmd_clr_adv,		"Clear advertising instances"	},
 	{ "appearance",		"<appearance>",
 		cmd_appearance,		"Set appearance"		},
+	{} },
 };
 
-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) {
-		cmd_usage(argv[0]);
-		return;
-	}
-
-	mgmt_cancel_all(mgmt);
-	mgmt_unregister_all(mgmt);
-
-	set_index(argv[1]);
-
-	register_mgmt_callbacks(mgmt, mgmt_index);
-
-	print("Selected index %u", mgmt_index);
-
-	update_prompt(mgmt_index);
-}
-
-static struct cmd_info interactive_cmd[] = {
-	{ "select",	"<index>",
-			cmd_select,	"Select a different index"	},
-	{ "quit",	NULL,
-			cmd_quit,	"Exit program"			},
-	{ "exit",	NULL,
-			cmd_quit,	"Exit program"			},
-	{ "help",	NULL,
-			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 cmd_usage(char *cmd)
-{
-	struct cmd_info *c;
-
-	if (!cmd)
-		return;
-
-	c = find_cmd(cmd, all_cmd, NELEM(all_cmd));
-	if (!c && interactive) {
-		c = find_cmd(cmd, interactive_cmd, NELEM(interactive_cmd));
-		if (!c)
-			return;
-		error("Usage: %s %s", cmd, c->arg ? : "");
-		return;
-	}
-
-	if (!c)
-		return;
-
-	print("Usage: %s %s", cmd, c->arg ? : "");
-
-}
-
-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;
-
-	if (history_search(input, -1))
-		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 ((int)strlen(c->arg ? : "") <=
-					(int)(25 - strlen(c->cmd)))
-			printf("  %s %-*s %s\n", c->cmd,
-					(int)(25 - strlen(c->cmd)),
-					c->arg ? : "",
-					c->doc ? : "");
-		else
-			printf("  %s %-s\n" "  %s %-25s %s\n",
-					c->cmd,
-					c->arg ? : "",
-					"", "",
-					c->doc ? : "");
-	}
-
-	if (!interactive)
-		goto free_we;
-
-	for (i = 0; i < NELEM(interactive_cmd); i++) {
-		c = &interactive_cmd[i];
-		if ((int)strlen(c->arg ? : "") <=
-					(int)(25 - strlen(c->cmd)))
-			printf("  %s %-*s %s\n", c->cmd,
-					(int)(25 - strlen(c->cmd)),
-					c->arg ? : "",
-					c->doc ? : "");
-		else
-			printf("  %s %-s\n" "  %s %-25s %s\n",
-					c->cmd,
-					c->arg ? : "",
-					"", "",
-					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;
@@ -4807,29 +4370,35 @@
 	print("%s%s", prefix, str);
 }
 
+static const char *index_option;
+
+static struct option main_options[] = {
+	{ "index",	1, 0, 'i' },
+	{ 0, 0, 0, 0 }
+};
+
+static const char **optargs[] = {
+	&index_option
+};
+
+static const char *help[] = {
+	"Specify adapter index\n"
+};
+
+static const struct bt_shell_opt opt = {
+	.options = main_options,
+	.optno = sizeof(main_options) / sizeof(struct option),
+	.optstr = "i:V",
+	.optarg = optargs,
+	.help = help,
+};
+
 int main(int argc, char *argv[])
 {
-	struct io *input;
-	int status, opt;
+	int status;
 
-	while ((opt = getopt_long(argc, argv, "+hi:",
-						main_options, NULL)) != -1) {
-		switch (opt) {
-		case 'i':
-			set_index(optarg);
-			break;
-		case 'h':
-		default:
-			usage();
-			return 0;
-		}
-	}
-
-	argc -= optind;
-	argv += optind;
-	optind = 0;
-
-	mainloop_init();
+	bt_shell_init(argc, argv, &opt);
+	bt_shell_set_menu(&main_menu);
 
 	mgmt = mgmt_new_default();
 	if (!mgmt) {
@@ -4840,47 +4409,14 @@
 	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, mgmt_index, argc, argv);
-	}
+	if (index_option)
+		set_index(index_option);
 
 	register_mgmt_callbacks(mgmt, 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(mgmt_index);
-		rl_redisplay();
-	}
-
-	status = mainloop_run();
-
-	if (input) {
-		io_destroy(input);
-
-		rl_message("");
-		rl_callback_handler_remove();
-	}
+	bt_shell_attach(fileno(stdin));
+	update_prompt(mgmt_index);
+	bt_shell_run();
 
 	mgmt_cancel_all(mgmt);
 	mgmt_unregister_all(mgmt);