Linux bluetooth development
 help / color / mirror / Atom feed
* [RFC 0/4] hcimgmt: command line tool for mgmt interface
@ 2011-04-15 17:57 Vinicius Costa Gomes
  2011-04-15 17:57 ` [RFC 1/4] Add hcimgmt command line test tool Vinicius Costa Gomes
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Vinicius Costa Gomes @ 2011-04-15 17:57 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes

Hi,

When the mgmt interface was first proposed Johan sent a patch
that introduced this tool, I updated it for the current MGMT API
and added a couple new commands.


--
Cheers,


Johan Hedberg (1):
  Add hcimgmt command line test tool

Vinicius Costa Gomes (3):
  hcimgmt: Add command to set IO Capabilities
  Add command to clear the link key list via MGMT interface
  hcimgmt: add support for setting pairable mode

 Makefile.tools  |    5 +-
 tools/hcimgmt.c |  546 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 550 insertions(+), 1 deletions(-)
 create mode 100644 tools/hcimgmt.c

--
1.7.4.3


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [RFC 1/4] Add hcimgmt command line test tool
  2011-04-15 17:57 [RFC 0/4] hcimgmt: command line tool for mgmt interface Vinicius Costa Gomes
@ 2011-04-15 17:57 ` Vinicius Costa Gomes
  2011-04-15 17:57 ` [RFC 2/4] hcimgmt: Add command to set IO Capabilities Vinicius Costa Gomes
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Vinicius Costa Gomes @ 2011-04-15 17:57 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Johan Hedberg

From: Johan Hedberg <johan.hedberg@nokia.com>

---
 Makefile.tools  |    5 +-
 tools/hcimgmt.c |  362 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 366 insertions(+), 1 deletions(-)
 create mode 100644 tools/hcimgmt.c

diff --git a/Makefile.tools b/Makefile.tools
index 364db37..98fb99c 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -5,7 +5,7 @@ conf_DATA += tools/rfcomm.conf
 endif
 
 bin_PROGRAMS += tools/rfcomm tools/l2ping \
-				tools/hcitool tools/sdptool tools/ciptool
+			tools/hcitool tools/sdptool tools/ciptool tools/hcimgmt
 
 sbin_PROGRAMS += tools/hciattach tools/hciconfig
 
@@ -38,6 +38,9 @@ tools_hcitool_SOURCES = tools/hcitool.c src/oui.h src/oui.c \
 						src/textfile.h src/textfile.c
 tools_hcitool_LDADD = lib/libbluetooth.la
 
+tools_hcimgmt_SOURCES = tools/hcimgmt.c
+tools_hcimgmt_LDADD = lib/libbluetooth.la
+
 tools_sdptool_SOURCES = tools/sdptool.c src/sdp-xml.h src/sdp-xml.c
 tools_sdptool_LDADD = lib/libbluetooth.la
 
diff --git a/tools/hcimgmt.c b/tools/hcimgmt.c
new file mode 100644
index 0000000..99338ed
--- /dev/null
+++ b/tools/hcimgmt.c
@@ -0,0 +1,362 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2010  Nokia Corporation
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/hci.h>
+#include <bluetooth/hci_lib.h>
+#include <bluetooth/mgmt.h>
+
+#define MGMT_BUF_SIZE 1024
+
+#define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, NULL)) != -1)
+
+static void usage(void);
+
+/* Display local devices */
+
+static struct option dev_options[] = {
+	{ "help",	0, 0, 'h' },
+	{0, 0, 0, 0 }
+};
+
+static int hci_open_channel(int dev_id, unsigned short channel)
+{
+	struct sockaddr_hci a;
+	int dd, err;
+
+	/* Create HCI socket */
+	dd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
+	if (dd < 0)
+		return -errno;
+
+	/* Bind socket to the HCI device */
+	memset(&a, 0, sizeof(a));
+	a.hci_family = AF_BLUETOOTH;
+	a.hci_dev = dev_id;
+	a.hci_channel = channel;
+	if (bind(dd, (struct sockaddr *) &a, sizeof(a)) < 0) {
+		err = -errno;
+		goto fail;
+	}
+
+	return dd;
+
+fail:
+	close(dd);
+	return err;
+}
+
+static ssize_t hci_mgmt_cmd(int dd, uint16_t index, uint16_t opcode, void *data,
+		uint16_t len, uint16_t rsp_ev, void *rsp, uint16_t rsp_len)
+{
+	ssize_t ret;
+	size_t copied, plen;
+	struct mgmt_hdr hdr = { htobs(opcode), htobs(index), htobs(len) };
+	struct mgmt_ev_cmd_complete *cc;
+	char buf[MGMT_BUF_SIZE];
+
+	memcpy(buf, &hdr, sizeof(hdr));
+	memcpy(buf + sizeof(hdr), data, len);
+
+	ret = write(dd, buf, sizeof(hdr) + len);
+	if (ret < 0)
+		return -errno;
+
+	ret = read(dd, buf, sizeof(buf));
+	if (ret < 0)
+		return -errno;
+
+	if (ret < (ssize_t) sizeof(struct mgmt_hdr)) {
+		fprintf(stderr,
+			"ret (%zd) != sizeof(struct mgmt_hdr) (%zu)\n",
+					ret, sizeof(struct mgmt_hdr));
+		return -EIO;
+	}
+
+	memcpy(&hdr, buf, sizeof(hdr));
+
+	if (btohs(hdr.len) != ret - sizeof(hdr)) {
+		fprintf(stderr, "hdr.len (%u) != ret - sizeof(hdr) (%zu)\n",
+					btohs(hdr.len), ret - sizeof(hdr));
+		return -EIO;
+	}
+
+	if (btohs(hdr.opcode) != rsp_ev) {
+		fprintf(stderr, "hdr.opcode (%u) != rsp_ev (%u)\n",
+						btohs(hdr.opcode), rsp_ev);
+		return -EIO;
+	}
+
+	cc = (void *) &buf[sizeof(hdr)];
+
+	if (btohs(cc->opcode) != opcode) {
+		fprintf(stderr, "cc.opcode (%u) != opcode (%u)\n",
+						btohs(cc->opcode), opcode);
+		return -EIO;
+	}
+
+	/* sizeof(opcode) == 2 */
+	plen = btohs(hdr.len) - 2;
+	copied = rsp_len < plen ? plen : rsp_len;
+
+	memcpy(rsp, cc->data, copied);
+
+	return copied;
+}
+
+static void print_bytes(uint8_t *bytes, size_t count)
+{
+	size_t i;
+
+	for (i = 0; i < count; i++)
+		printf("%02x ", bytes[i]);
+}
+
+static void cmd_features(int dev_id, int argc, char **argv)
+{
+	int dd;
+	ssize_t ret;
+	struct mgmt_rp_read_features rp;
+
+	dd = hci_open_channel(HCI_DEV_NONE, HCI_CHANNEL_CONTROL);
+	if (dd < 0) {
+		perror("HCI Control socket open failed");
+		exit(1);
+	}
+
+	ret = hci_mgmt_cmd(dd, MGMT_INDEX_NONE, MGMT_OP_READ_FEATURES, NULL, 0,
+				MGMT_EV_CMD_COMPLETE, &rp, sizeof(rp));
+	if (ret < 0) {
+		fprintf(stderr, "Command failed: %s (%zd)\n",
+							strerror(-ret), -ret);
+		exit(1);
+	}
+
+	printf("HCI Control API features: ");
+	print_bytes(rp.features, 8);
+	printf("\n");
+}
+
+static void cmd_version(int dev_id, int argc, char **argv)
+{
+	int dd;
+	ssize_t ret;
+	struct mgmt_rp_read_version rp;
+
+	dd = hci_open_channel(HCI_DEV_NONE, HCI_CHANNEL_CONTROL);
+	if (dd < 0) {
+		perror("HCI Control socket open failed");
+		exit(1);
+	}
+
+	ret = hci_mgmt_cmd(dd, dev_id, MGMT_OP_READ_VERSION, NULL, 0,
+			MGMT_EV_CMD_COMPLETE, &rp, sizeof(rp));
+	if (ret < 0) {
+		fprintf(stderr, "Command failed: %s (%zd)\n",
+							strerror(-ret), -ret);
+		exit(1);
+	}
+
+	printf("HCI Control API version %u.%u\n", rp.version,
+							btohs(rp.revision));
+}
+
+static const char *dev_help =
+	"Usage:\n"
+	"\tdev\n";
+
+static void cmd_dev(int dev_id, int argc, char **argv)
+{
+	int opt, dd, i;
+	ssize_t ret;
+	uint16_t *ptr;
+	struct mgmt_rp_read_index_list rp;
+
+	for_each_opt(opt, dev_options, NULL) {
+		switch (opt) {
+		default:
+			printf("%s", dev_help);
+			return;
+		}
+	}
+
+	dd = hci_open_channel(HCI_DEV_NONE, HCI_CHANNEL_CONTROL);
+	if (dd < 0) {
+		perror("HCI Control socket open failed");
+		exit(1);
+	}
+
+	ret = hci_mgmt_cmd(dd, MGMT_INDEX_NONE, MGMT_OP_READ_INDEX_LIST,
+				NULL, 0, MGMT_EV_CMD_COMPLETE, &rp, sizeof(rp));
+	if (ret < 0) {
+		fprintf(stderr, "Failed\n");
+		exit(1);
+	}
+
+	ptr = rp.index;
+	for (i = 0; i < btohs(rp.num_controllers); i++, ptr += 2) {
+		uint16_t index;
+		memcpy(&index, ptr, 2);
+		printf("hci%u ", btohs(index));
+	}
+
+	printf("\n");
+}
+
+static void cmd_info(int dev_id, int argc, char **argv)
+{
+	int dd;
+	uint16_t id;
+	ssize_t ret;
+	char addr[18];
+	struct mgmt_rp_read_info rp;
+
+	dd = hci_open_channel(HCI_DEV_NONE, HCI_CHANNEL_CONTROL);
+	if (dd < 0) {
+		perror("HCI Control socket open failed");
+		exit(1);
+	}
+
+	if (dev_id < 0) {
+		dev_id = hci_get_route(NULL);
+		if (dev_id < 0) {
+			perror("Device is not available");
+			exit(1);
+		}
+	}
+
+	id = (uint16_t) dev_id;
+
+	ret = hci_mgmt_cmd(dd, id, MGMT_OP_READ_INFO, NULL, 0,
+				MGMT_EV_CMD_COMPLETE, &rp, sizeof(rp));
+	if (ret < 0) {
+		fprintf(stderr, "Command failed: %s (%zd)\n",
+							strerror(-ret), -ret);
+		exit(1);
+	}
+
+	ba2str(&rp.bdaddr, addr);
+
+	printf("hci%u type %u addr %s features ", btohs(id), rp.type, addr);
+	print_bytes(rp.features, 8);
+	printf("\n");
+}
+
+static struct {
+	char *cmd;
+	void (*func)(int dev_id, int argc, char **argv);
+	char *doc;
+} command[] = {
+	{ "dev",	cmd_dev,	"Display local devices"	},
+	{ "version",	cmd_version,	"Display version"	},
+	{ "features",	cmd_features,	"Control API features"	},
+	{ "info",	cmd_info,	"Read controller info"	},
+	{ NULL, NULL, 0 }
+};
+
+static void usage(void)
+{
+	int i;
+
+	printf("hcictl - HCI Control ver %s\n", VERSION);
+	printf("Usage:\n"
+		"\thcictl [options] <command> [command parameters]\n");
+	printf("Options:\n"
+		"\t--help\tDisplay help\n"
+		"\t-i dev\tHCI device\n");
+	printf("Commands:\n");
+	for (i = 0; command[i].cmd; i++)
+		printf("\t%-4s\t%s\n", command[i].cmd,
+		command[i].doc);
+	printf("\n"
+		"For more information on the usage of each command use:\n"
+		"\thcictl <command> --help\n" );
+}
+
+static struct option main_options[] = {
+	{ "help",	0, 0, 'h' },
+	{ "device",	1, 0, 'i' },
+	{ 0, 0, 0, 0 }
+};
+
+int main(int argc, char *argv[])
+{
+	int opt, i, dev_id = -1;
+	bdaddr_t ba;
+
+	while ((opt = getopt_long(argc, argv, "+i:h", main_options,
+							NULL)) != -1) {
+		switch (opt) {
+		case 'i':
+			dev_id = hci_devid(optarg);
+			if (dev_id < 0) {
+				perror("Invalid device");
+				exit(1);
+			}
+			break;
+
+		case 'h':
+		default:
+			usage();
+			exit(0);
+		}
+	}
+
+	argc -= optind;
+	argv += optind;
+	optind = 0;
+
+	if (argc < 1) {
+		usage();
+		exit(0);
+	}
+
+	if (dev_id != -1 && hci_devba(dev_id, &ba) < 0) {
+		perror("Device is not available");
+		exit(1);
+	}
+
+	for (i = 0; command[i].cmd; i++) {
+		if (strncmp(command[i].cmd, argv[0], strlen(command[1].cmd)))
+			continue;
+		command[i].func(dev_id, argc, argv);
+		break;
+	}
+	return 0;
+}
-- 
1.7.4.3


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [RFC 2/4] hcimgmt: Add command to set IO Capabilities
  2011-04-15 17:57 [RFC 0/4] hcimgmt: command line tool for mgmt interface Vinicius Costa Gomes
  2011-04-15 17:57 ` [RFC 1/4] Add hcimgmt command line test tool Vinicius Costa Gomes
@ 2011-04-15 17:57 ` Vinicius Costa Gomes
  2011-04-15 17:57 ` [RFC 3/4] Add command to clear the link key list via MGMT interface Vinicius Costa Gomes
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Vinicius Costa Gomes @ 2011-04-15 17:57 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes

---
 tools/hcimgmt.c |   80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 80 insertions(+), 0 deletions(-)

diff --git a/tools/hcimgmt.c b/tools/hcimgmt.c
index 99338ed..fc88654 100644
--- a/tools/hcimgmt.c
+++ b/tools/hcimgmt.c
@@ -46,6 +46,31 @@
 
 #define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, NULL)) != -1)
 
+static void helper_arg(int min_num_arg, int max_num_arg, int *argc,
+			char ***argv, const char *usage)
+{
+	*argc -= optind;
+	/* too many arguments, but when "max_num_arg < min_num_arg" then no
+		 limiting (prefer "max_num_arg=-1" to gen infinity)
+	*/
+	if ( (*argc > max_num_arg) && (max_num_arg >= min_num_arg ) ) {
+		fprintf(stderr, "%s: too many arguments (maximal: %i)\n",
+				*argv[0], max_num_arg);
+		printf("%s", usage);
+		exit(1);
+	}
+
+	/* print usage */
+	if (*argc < min_num_arg) {
+		fprintf(stderr, "%s: too few arguments (minimal: %i)\n",
+				*argv[0], min_num_arg);
+		printf("%s", usage);
+		exit(0);
+	}
+
+	*argv += optind;
+}
+
 static void usage(void);
 
 /* Display local devices */
@@ -131,6 +156,9 @@ static ssize_t hci_mgmt_cmd(int dd, uint16_t index, uint16_t opcode, void *data,
 		return -EIO;
 	}
 
+	if (rsp == NULL)
+		return 0;
+
 	/* sizeof(opcode) == 2 */
 	plen = btohs(hdr.len) - 2;
 	copied = rsp_len < plen ? plen : rsp_len;
@@ -278,6 +306,57 @@ static void cmd_info(int dev_id, int argc, char **argv)
 	printf("\n");
 }
 
+static struct option setiocap_options[] = {
+	{ "help",	0, 0, 'h' },
+	{ 0, 0, 0, 0 }
+};
+
+static const char *setiocap_help =
+	"Usage:\n"
+	"\tsetiocap <value>\n";
+
+static void cmd_setiocap(int dev_id, int argc, char **argv)
+{
+	int opt, dd;
+	ssize_t ret;
+	struct mgmt_cp_set_io_capability cp;
+
+	for_each_opt(opt, setiocap_options, NULL) {
+		switch (opt) {
+		default:
+			printf("%s", setiocap_help);
+			return;
+		}
+	}
+
+	helper_arg(1, 1, &argc, &argv, setiocap_help);
+
+	memset(&cp, 0, sizeof(cp));
+	cp.io_capability = (uint8_t) strtol(argv[0], NULL, 0);
+
+	dd = hci_open_channel(HCI_DEV_NONE, HCI_CHANNEL_CONTROL);
+	if (dd < 0) {
+		perror("HCI Control socket open failed");
+		exit(1);
+	}
+
+	if (dev_id < 0) {
+		dev_id = hci_get_route(NULL);
+		if (dev_id < 0) {
+			perror("Device is not available");
+			exit(1);
+		}
+	}
+
+	ret = hci_mgmt_cmd(dd, dev_id, MGMT_OP_SET_IO_CAPABILITY, &cp, sizeof(cp),
+				MGMT_EV_CMD_COMPLETE, NULL, 0);
+	if (ret < 0) {
+		fprintf(stderr, "Command failed: %s (%zd)\n",
+							strerror(-ret), -ret);
+		exit(1);
+	}
+}
+
 static struct {
 	char *cmd;
 	void (*func)(int dev_id, int argc, char **argv);
@@ -287,6 +366,7 @@ static struct {
 	{ "version",	cmd_version,	"Display version"	},
 	{ "features",	cmd_features,	"Control API features"	},
 	{ "info",	cmd_info,	"Read controller info"	},
+	{ "setiocap",	cmd_setiocap,	"Set IO Capabilities"	},
 	{ NULL, NULL, 0 }
 };
 
-- 
1.7.4.3


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [RFC 3/4] Add command to clear the link key list via MGMT interface
  2011-04-15 17:57 [RFC 0/4] hcimgmt: command line tool for mgmt interface Vinicius Costa Gomes
  2011-04-15 17:57 ` [RFC 1/4] Add hcimgmt command line test tool Vinicius Costa Gomes
  2011-04-15 17:57 ` [RFC 2/4] hcimgmt: Add command to set IO Capabilities Vinicius Costa Gomes
@ 2011-04-15 17:57 ` Vinicius Costa Gomes
  2011-04-15 17:57 ` [RFC 4/4] hcimgmt: add support for setting pairable mode Vinicius Costa Gomes
  2011-04-16  0:59 ` [RFC 0/4] hcimgmt: command line tool for mgmt interface Marcel Holtmann
  4 siblings, 0 replies; 6+ messages in thread
From: Vinicius Costa Gomes @ 2011-04-15 17:57 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes

---
 tools/hcimgmt.c |   51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 51 insertions(+), 0 deletions(-)

diff --git a/tools/hcimgmt.c b/tools/hcimgmt.c
index fc88654..7744344 100644
--- a/tools/hcimgmt.c
+++ b/tools/hcimgmt.c
@@ -357,6 +357,56 @@ static void cmd_setiocap(int dev_id, int argc, char **argv)
 	}
 }
 
+static struct option clearkeys_options[] = {
+	{ "help",	0, 0, 'h' },
+	{ 0, 0, 0, 0 }
+};
+
+static const char *clearkeys_help =
+	"Usage:\n"
+	"\tclearkeys\n";
+
+static void cmd_clearkeys(int dev_id, int argc, char **argv)
+{
+	int opt, dd;
+	ssize_t ret;
+	struct mgmt_cp_load_keys cp;
+
+	for_each_opt(opt, clearkeys_options, NULL) {
+		switch (opt) {
+		default:
+			printf("%s", clearkeys_help);
+			return;
+		}
+	}
+
+	helper_arg(0, 0, &argc, &argv, setiocap_help);
+
+	memset(&cp, 0, sizeof(cp));
+
+	dd = hci_open_channel(HCI_DEV_NONE, HCI_CHANNEL_CONTROL);
+	if (dd < 0) {
+		perror("HCI Control socket open failed");
+		exit(1);
+	}
+
+	if (dev_id < 0) {
+		dev_id = hci_get_route(NULL);
+		if (dev_id < 0) {
+			perror("Device is not available");
+			exit(1);
+		}
+	}
+
+	ret = hci_mgmt_cmd(dd, dev_id, MGMT_OP_LOAD_KEYS, &cp, sizeof(cp),
+				MGMT_EV_CMD_COMPLETE, NULL, 0);
+	if (ret < 0) {
+		fprintf(stderr, "Command failed: %s (%zd)\n",
+							strerror(-ret), -ret);
+		exit(1);
+	}
+}
+
 static struct {
 	char *cmd;
 	void (*func)(int dev_id, int argc, char **argv);
@@ -367,6 +417,7 @@ static struct {
 	{ "features",	cmd_features,	"Control API features"	},
 	{ "info",	cmd_info,	"Read controller info"	},
 	{ "setiocap",	cmd_setiocap,	"Set IO Capabilities"	},
+	{ "clearkeys",  cmd_clearkeys,	"Clear key list"	},
 	{ NULL, NULL, 0 }
 };
 
-- 
1.7.4.3


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [RFC 4/4] hcimgmt: add support for setting pairable mode
  2011-04-15 17:57 [RFC 0/4] hcimgmt: command line tool for mgmt interface Vinicius Costa Gomes
                   ` (2 preceding siblings ...)
  2011-04-15 17:57 ` [RFC 3/4] Add command to clear the link key list via MGMT interface Vinicius Costa Gomes
@ 2011-04-15 17:57 ` Vinicius Costa Gomes
  2011-04-16  0:59 ` [RFC 0/4] hcimgmt: command line tool for mgmt interface Marcel Holtmann
  4 siblings, 0 replies; 6+ messages in thread
From: Vinicius Costa Gomes @ 2011-04-15 17:57 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes

---
 tools/hcimgmt.c |   55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 54 insertions(+), 1 deletions(-)

diff --git a/tools/hcimgmt.c b/tools/hcimgmt.c
index 7744344..9998982 100644
--- a/tools/hcimgmt.c
+++ b/tools/hcimgmt.c
@@ -407,6 +407,58 @@ static void cmd_clearkeys(int dev_id, int argc, char **argv)
 	}
 }
 
+static struct option pairable_options[] = {
+	{ "help",	0, 0, 'h' },
+	{ 0, 0, 0, 0 }
+};
+
+static const char *pairable_help =
+	"Usage:\n"
+	"\tclearkeys <1|0>\n";
+
+static void cmd_pairable(int dev_id, int argc, char **argv)
+{
+	int opt, dd;
+	ssize_t ret;
+	struct mgmt_mode cp;
+
+	for_each_opt(opt, pairable_options, NULL) {
+		switch (opt) {
+		default:
+			printf("%s", pairable_help);
+			return;
+		}
+	}
+
+	helper_arg(1, 1, &argc, &argv, pairable_help);
+
+	memset(&cp, 0, sizeof(cp));
+
+	dd = hci_open_channel(HCI_DEV_NONE, HCI_CHANNEL_CONTROL);
+	if (dd < 0) {
+		perror("HCI Control socket open failed");
+		exit(1);
+	}
+
+	if (dev_id < 0) {
+		dev_id = hci_get_route(NULL);
+		if (dev_id < 0) {
+			perror("Device is not available");
+			exit(1);
+		}
+	}
+
+	cp.val = (uint8_t) strtol(argv[0], NULL, 0);
+
+	ret = hci_mgmt_cmd(dd, dev_id, MGMT_OP_SET_PAIRABLE, &cp, sizeof(cp),
+				MGMT_EV_CMD_COMPLETE, NULL, 0);
+	if (ret < 0) {
+		fprintf(stderr, "Command failed: %s (%zd)\n",
+							strerror(-ret), -ret);
+		exit(1);
+	}
+}
+
 static struct {
 	char *cmd;
 	void (*func)(int dev_id, int argc, char **argv);
@@ -417,7 +469,8 @@ static struct {
 	{ "features",	cmd_features,	"Control API features"	},
 	{ "info",	cmd_info,	"Read controller info"	},
 	{ "setiocap",	cmd_setiocap,	"Set IO Capabilities"	},
-	{ "clearkeys",  cmd_clearkeys,	"Clear key list"	},
+	{ "clearkeys",	cmd_clearkeys,	"Clear key list"	},
+	{ "pairable",	cmd_pairable,	"Set pairable mode"	},
 	{ NULL, NULL, 0 }
 };
 
-- 
1.7.4.3


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [RFC 0/4] hcimgmt: command line tool for mgmt interface
  2011-04-15 17:57 [RFC 0/4] hcimgmt: command line tool for mgmt interface Vinicius Costa Gomes
                   ` (3 preceding siblings ...)
  2011-04-15 17:57 ` [RFC 4/4] hcimgmt: add support for setting pairable mode Vinicius Costa Gomes
@ 2011-04-16  0:59 ` Marcel Holtmann
  4 siblings, 0 replies; 6+ messages in thread
From: Marcel Holtmann @ 2011-04-16  0:59 UTC (permalink / raw)
  To: Vinicius Costa Gomes; +Cc: linux-bluetooth

Hi Vinicious,

> When the mgmt interface was first proposed Johan sent a patch
> that introduced this tool, I updated it for the current MGMT API
> and added a couple new commands.

overall I like to have a tool called bt in similar fashion like iw, ip
etc. And I really want the hci* prefix getting out of tools namespace.

Regards

Marcel



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2011-04-16  0:59 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-04-15 17:57 [RFC 0/4] hcimgmt: command line tool for mgmt interface Vinicius Costa Gomes
2011-04-15 17:57 ` [RFC 1/4] Add hcimgmt command line test tool Vinicius Costa Gomes
2011-04-15 17:57 ` [RFC 2/4] hcimgmt: Add command to set IO Capabilities Vinicius Costa Gomes
2011-04-15 17:57 ` [RFC 3/4] Add command to clear the link key list via MGMT interface Vinicius Costa Gomes
2011-04-15 17:57 ` [RFC 4/4] hcimgmt: add support for setting pairable mode Vinicius Costa Gomes
2011-04-16  0:59 ` [RFC 0/4] hcimgmt: command line tool for mgmt interface Marcel Holtmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox