From c98b2f82a4e532ca61592b08e3ad60749eb9f8d7 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 8 Mar 2002 21:12:35 +0000 Subject: Initial revision --- tools/hcitool.c | 368 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 368 insertions(+) create mode 100644 tools/hcitool.c (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c new file mode 100644 index 00000000..4d6380fb --- /dev/null +++ b/tools/hcitool.c @@ -0,0 +1,368 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +extern int optind,opterr,optopt; +extern char *optarg; + +static int ctl; + +static int for_each_dev(int flag, int(*func)(int d, long arg), long arg) +{ + struct hci_dev_list_req *dl; + struct hci_dev_req *dr; + int i; + + dl = malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t)); + if (!dl) { + perror("Can't allocate memory"); + return -1; + } + dl->dev_num = HCI_MAX_DEV; + dr = dl->dev_req; + + if (ioctl(ctl, HCIGETDEVLIST, (void*)dl)) { + perror("Can't get device list"); + return -1; + } + + if (!dl->dev_num) + return -1; + + for (i=0; i < dl->dev_num; i++, dr++) { + if (dr->dev_opt & (1<dev_id, arg)) + return dr->dev_id; + } + } + return -1; +} + +static int other_bdaddr(int dev_id, long arg) +{ + struct hci_dev_info di = {dev_id: dev_id}; + if (ioctl(ctl, HCIGETDEVINFO, (void*) &di)) + return 0; + return bacmp((bdaddr_t *)arg, &di.bdaddr); +} + +static int get_route(bdaddr_t *bdaddr) +{ + if (bdaddr) + return for_each_dev(HCI_UP, other_bdaddr, (long) bdaddr); + else + return for_each_dev(HCI_UP, NULL, 0); +} + +static int dev_info(int dev_id, long arg) +{ + struct hci_dev_info di = {dev_id: dev_id}; + bdaddr_t bdaddr; + if (ioctl(ctl, HCIGETDEVINFO, (void*) &di)) + return 0; + + baswap(&bdaddr, &di.bdaddr); + printf("\t%s\t%s\n", di.name, batostr(&bdaddr)); + return 0; +} + +static int conn_list(int dev_id, long arg) +{ + struct hci_conn_list_req *cl; + struct hci_conn_info *ci; + int i; + + if (!(cl = malloc(10 * sizeof(*ci) + sizeof(*cl)))) { + perror("Can't allocate memory"); + exit(1); + } + cl->dev_id = dev_id; + cl->conn_num = 10; + ci = cl->conn_info; + + if (ioctl(ctl, HCIGETCONNLIST, (void*)cl)) { + perror("Can't get connection list"); + exit(1); + } + + for (i=0; i < cl->conn_num; i++, ci++) { + bdaddr_t bdaddr; + baswap(&bdaddr, &ci->bdaddr); + printf("\t%s %s %s handle %d state %d lm %s\n", + ci->out ? "<" : ">", + ci->type == ACL_LINK ? "ACL" : "SCO", + batostr(&bdaddr), ci->handle, + ci->state, + hci_lmtostr(ci->link_mode)); + } + return 0; +} + +static int find_conn(int dev_id, long arg) +{ + struct hci_conn_list_req *cl; + struct hci_conn_info *ci; + int i; + + if (!(cl = malloc(10 * sizeof(*ci) + sizeof(*cl)))) { + perror("Can't allocate memory"); + exit(1); + } + cl->dev_id = dev_id; + cl->conn_num = 10; + ci = cl->conn_info; + + if (ioctl(ctl, HCIGETCONNLIST, (void*)cl)) { + perror("Can't get connection list"); + exit(1); + } + + for (i=0; i < cl->conn_num; i++, ci++) + if (!bacmp((bdaddr_t *)arg, &ci->bdaddr)) + return 1; + return 0; +} + +static void cmd_dev(int dev_id, char **opt, int nopt) +{ + printf("Devices:\n"); + for_each_dev(HCI_UP, dev_info, 0); +} + +static void cmd_inq(int dev_id, char **opt, int nopt) +{ + inquiry_info *info; + int i, num_rsp = 0, length, flags; + bdaddr_t bdaddr; + + if (dev_id < 0) + dev_id = get_route(NULL); + + if (nopt >= 1) + length = atoi(opt[0]); + else + length = 10; /* 10 seconds */ + + flags = 0; + if (nopt >= 2) + flags |= !strncasecmp("f", opt[1], 1) ? IREQ_CACHE_FLUSH : 0; + + printf("Inquiring ...\n"); + info = hci_inquiry(dev_id, length, &num_rsp, NULL, flags); + + if (!info) { + perror("Inquiry failed."); + exit(1); + } + + for (i = 0; i < num_rsp; i++) { + baswap(&bdaddr, &(info+i)->bdaddr); + printf("\t%s\tclock offset: 0x%4.4x\tclass: 0x%2.2x%2.2x%2.2x\n", + batostr(&bdaddr), (info+i)->clock_offset, + (info+i)->dev_class[2], + (info+i)->dev_class[1], + (info+i)->dev_class[0]); + } + free(info); +} + +static void cmd_con(int dev_id, char **opt, int nopt) +{ + printf("Connections:\n"); + if (dev_id < 0) + for_each_dev(HCI_UP, conn_list, 0); + else + conn_list(dev_id, 0); +} + +static void cmd_cc(int dev_id, char **opt, int nopt) +{ + bdaddr_t bdaddr; + int dd, ptype, role; + + if (nopt < 1) + return; + + baswap(&bdaddr, strtoba(opt[0])); + + if (dev_id < 0) { + dev_id = get_route(&bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Device is not available.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + if (nopt >= 2) + hci_strtoptype(opt[1], &ptype); + else + ptype = HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5; + + if (nopt >= 3) + role = !strncasecmp("m", opt[2], 1) ? 0 : 1; + else + role = 0; + + hci_create_connection(dd, &bdaddr, ptype, role, 1000); + + hci_close_dev(dd); +} + +static void cmd_dc(int dev_id, char **opt, int nopt) +{ + struct hci_conn_info_req *cr; + bdaddr_t bdaddr; + int dd; + + if (nopt < 1) + return; + + baswap(&bdaddr, strtoba(*opt)); + + if (dev_id < 0) { + dev_id = for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + hci_disconnect(dd, cr->conn_info->handle, 0, 100); + + close(dd); + free(cr); +} + +struct { + char *cmd; + void (*func)(int dev_id, char **opt, int nopt); + char *opt; + char *doc; +} command[] = { + { "dev", cmd_dev, 0, "Display local devices" }, + { "inq", cmd_inq, "[lenght] [flush]", "Inquire remote devices" }, + { "con", cmd_con, 0, "Display active connections" }, + { "cc", cmd_cc, " [pkt type] [role]", "Create connection to remote device" }, + { "dc", cmd_dc, "", "Disconnect from remote device" }, + { NULL, NULL, 0} +}; + +static void usage(void) +{ + int i; + + printf("hcitool - HCI Tool\n"); + printf("Usage:\n" + "\thcitool [-i hciX] [command]\n"); + printf("Commands:\n"); + for (i=0; command[i].cmd; i++) + printf("\t%-4s %-20s\t%s\n", command[i].cmd, + command[i].opt ? command[i].opt : " ", + command[i].doc); +} + +int main(int argc, char *argv[], char *env[]) +{ + int opt, i, dev_id = -1; + char *dev; + + while ((opt=getopt(argc, argv, "i:h")) != EOF) { + switch(opt) { + case 'i': + dev = strdup(optarg); + dev_id = atoi(dev + 3); + break; + + case 'h': + default: + usage(); + exit(0); + } + } + + if (argc - optind < 1) { + usage(); + exit(0); + } + + /* Open HCI socket */ + if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) { + perror("Can't open HCI socket."); + exit(1); + } + + for (i=0; command[i].cmd; i++) { + if (strncmp(command[i].cmd, argv[optind], 3)) + continue; + optind++; + command[i].func(dev_id, argv + optind, argc - optind); + break; + } + + close(ctl); + return 0; +} -- cgit From 945768a289b2114b26c0139f8875d1471a300c6b Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 22 Mar 2002 19:47:05 +0000 Subject: connect and disconnect fixes. --- tools/hcitool.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 4d6380fb..ed537031 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -219,7 +219,9 @@ static void cmd_con(int dev_id, char **opt, int nopt) static void cmd_cc(int dev_id, char **opt, int nopt) { bdaddr_t bdaddr; - int dd, ptype, role; + int ptype, dd; + uint16_t handle; + uint8_t role; if (nopt < 1) return; @@ -250,7 +252,7 @@ static void cmd_cc(int dev_id, char **opt, int nopt) else role = 0; - hci_create_connection(dd, &bdaddr, ptype, role, 1000); + hci_create_connection(dd, &bdaddr, ptype, role, 0, &handle, 1000); hci_close_dev(dd); } @@ -291,7 +293,7 @@ static void cmd_dc(int dev_id, char **opt, int nopt) exit(1); } - hci_disconnect(dd, cr->conn_info->handle, 0, 100); + hci_disconnect(dd, cr->conn_info->handle, 0x13, 100); close(dd); free(cr); -- cgit From acc7ace68c67f8bd356aaab04ce7b29914962607 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 22 Mar 2002 19:53:29 +0000 Subject: create_connection fix. --- tools/hcitool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index ed537031..aa6ac4ac 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -252,7 +252,7 @@ static void cmd_cc(int dev_id, char **opt, int nopt) else role = 0; - hci_create_connection(dd, &bdaddr, ptype, role, 0, &handle, 1000); + hci_create_connection(dd, &bdaddr, ptype, 0, role, &handle, 1000); hci_close_dev(dd); } -- cgit From 46ee343d9d3f6fe1786089b87402a24fc460144c Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 28 Mar 2002 01:32:42 +0000 Subject: Set default inquiry length to 10 seconds. --- tools/hcitool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index aa6ac4ac..bebdfbd4 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -182,7 +182,7 @@ static void cmd_inq(int dev_id, char **opt, int nopt) if (nopt >= 1) length = atoi(opt[0]); else - length = 10; /* 10 seconds */ + length = 8; /* ~ 10 seconds */ flags = 0; if (nopt >= 2) -- cgit From 4962b360716e1fd17a4f3cbddc7a305b4fd24668 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 9 Apr 2002 18:13:05 +0000 Subject: Added scan and rev commands. --- tools/hcitool.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 101 insertions(+), 2 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index bebdfbd4..70e4b56d 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -107,6 +107,55 @@ static int dev_info(int dev_id, long arg) return 0; } +static int rev_info(int dev_id, long arg) +{ + struct hci_version ver; + int dd; + + struct hci_request rq; + unsigned char buf[102]; + + + dd = hci_open_dev(dev_id); + if (dd < 0) { + printf("Can't open device hci%d. %s(%d)\n", dev_id, strerror(errno), errno); + return -1; + } + + if (hci_read_local_version(dd, &ver, 1000) < 0) { + printf("Can't read version info hci%d. %s(%d)\n", + dev_id, strerror(errno), errno); + return -1; + } + + printf("hci%d:", dev_id); + switch (ver.manufacturer) { + case 0: + memset(&rq, 0, sizeof(rq)); + rq.ogf = 0x3f; + rq.ocf = 0x000f; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &buf; + rq.rlen = sizeof(buf); + + if (hci_send_req(dd, &rq, 1000) < 0) { + printf("\n Can't read revision info. %s(%d)\n", + strerror(errno), errno); + return -1; + } + + printf("%s\n", buf + 1); + break; + default: + printf("\n Manufacturer not supported\n"); + break; + } + printf("\n"); + + return 0; +} + static int conn_list(int dev_id, long arg) { struct hci_conn_list_req *cl; @@ -207,6 +256,54 @@ static void cmd_inq(int dev_id, char **opt, int nopt) free(info); } +static void cmd_scan(int dev_id, char **opt, int nopt) +{ + inquiry_info *info; + int i, num_rsp = 0, length, flags; + bdaddr_t bdaddr; + int dd; + char name[248]; + + if (dev_id < 0) + dev_id = get_route(NULL); + + if (nopt >= 1) + length = atoi(opt[0]); + else + length = 8; /* ~ 10 seconds */ + + flags = 0; + if (nopt >= 2) + flags |= !strncasecmp("f", opt[1], 1) ? IREQ_CACHE_FLUSH : 0; + + printf("Scanning ...\n"); + info = hci_inquiry(dev_id, length, &num_rsp, NULL, flags); + + if (!info) { + perror("Inquiry failed."); + exit(1); + } + + for (i = 0; i < num_rsp; i++) { + dd = hci_open_dev(dev_id); + memset(name, 0, sizeof(name)); + if (hci_remote_name(dd, &(info+i)->bdaddr, sizeof(name), name, 100000) < 0) + strcpy(name, "n/a"); + close(dd); + baswap(&bdaddr, &(info+i)->bdaddr); + printf("\t%s\t%s\n", batostr(&bdaddr), name); + } + free(info); +} + +static void cmd_rev(int dev_id, char **opt, int nopt) +{ + if (dev_id < 0) + for_each_dev(HCI_UP, rev_info, 0); + else + rev_info(dev_id, 0); +} + static void cmd_con(int dev_id, char **opt, int nopt) { printf("Connections:\n"); @@ -305,8 +402,10 @@ struct { char *opt; char *doc; } command[] = { - { "dev", cmd_dev, 0, "Display local devices" }, - { "inq", cmd_inq, "[lenght] [flush]", "Inquire remote devices" }, + { "dev", cmd_dev, 0, "Display local devices" }, + { "rev", cmd_rev, 0, "Display revison information" }, + { "inq", cmd_inq, "[length] [flush]", "Inquire remote devices" }, + { "scan", cmd_scan, "[length] [flush]", "Scan for remote devices" }, { "con", cmd_con, 0, "Display active connections" }, { "cc", cmd_cc, " [pkt type] [role]", "Create connection to remote device" }, { "dc", cmd_dc, "", "Disconnect from remote device" }, -- cgit From 8720383cae063462a97c39f7bccdc5340a58594a Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 15 Apr 2002 16:53:32 +0000 Subject: Added "info" command --- tools/hcitool.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 6 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 70e4b56d..b30d93d1 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -296,6 +296,64 @@ static void cmd_scan(int dev_id, char **opt, int nopt) free(info); } +static void cmd_info(int dev_id, char **opt, int nopt) +{ + bdaddr_t bdaddr; + uint16_t handle; + int dd; + char name[248]; + unsigned char features[8]; + struct hci_version version; + + if (nopt < 1) + return; + + baswap(&bdaddr, strtoba(opt[0])); + + if (dev_id < 0) { + dev_id = get_route(&bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Device is not available.\n"); + exit(1); + } + } + + printf("Requesting information ...\n"); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + printf("\tBD Address: %s\n", opt[0]); + + if (hci_create_connection(dd, &bdaddr, 0x0008 | 0x0010, 0, 0, &handle, 25000) < 0) { + close(dd); + exit(1); + } + + if (hci_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0) + printf("\tDevice Name: %s\n", name); + + if (hci_read_remote_version(dd, handle, &version, 20000) == 0) { + printf("\tLMP Version: %s (0x%x) LMP Subversion: 0x%x\n" + "\tManufacturer: %s (%d)\n", + lmp_vertostr(version.lmp_ver), version.lmp_ver, version.lmp_subver, + bt_compidtostr(version.manufacturer), version.manufacturer); + } + + if (hci_read_remote_features(dd, handle, features, 20000) == 0) { + printf("\tFeatures:\n%s\n", + lmp_featurestostr(features, "\t\t", 3)); + } + + hci_disconnect(dd, handle, 0x13, 10000); + + close(dd); + +} + static void cmd_rev(int dev_id, char **opt, int nopt) { if (dev_id < 0) @@ -402,13 +460,14 @@ struct { char *opt; char *doc; } command[] = { - { "dev", cmd_dev, 0, "Display local devices" }, - { "rev", cmd_rev, 0, "Display revison information" }, - { "inq", cmd_inq, "[length] [flush]", "Inquire remote devices" }, - { "scan", cmd_scan, "[length] [flush]", "Scan for remote devices" }, - { "con", cmd_con, 0, "Display active connections" }, + { "dev", cmd_dev, 0, "Display local devices" }, + { "rev", cmd_rev, 0, "Display revison information" }, + { "inq", cmd_inq, "[length] [flush]", "Inquire remote devices" }, + { "scan", cmd_scan, "[length] [flush]", "Scan for remote devices" }, + { "info", cmd_info, "", "Get information from remote device" }, + { "con", cmd_con, 0, "Display active connections" }, { "cc", cmd_cc, " [pkt type] [role]", "Create connection to remote device" }, - { "dc", cmd_dc, "", "Disconnect from remote device" }, + { "dc", cmd_dc, "", "Disconnect from remote device" }, { NULL, NULL, 0} }; -- cgit From c4f18f46436d80592fa3bd500b74737a5e349a56 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 19 Apr 2002 01:26:12 +0000 Subject: Simplified 'cmd' command --- tools/hcitool.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index b30d93d1..b5256300 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -32,12 +32,14 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include @@ -48,6 +50,8 @@ extern char *optarg; static int ctl; +static void usage(void); + static int for_each_dev(int flag, int(*func)(int d, long arg), long arg) { struct hci_dev_list_req *dl; @@ -213,6 +217,23 @@ static int find_conn(int dev_id, long arg) return 0; } +static void hex_dump(char *pref, int width, unsigned char *buf, int len) +{ + register int i,n; + + for (i=0, n=1; i 0x3f) || (htobs(ocf) > 0x3ff)) { + usage(); + return; + } + + for (i = 2, len = 0; i < nopt && len < sizeof(buf); i++, len++) + *ptr++ = (uint8_t) strtol(opt[i], NULL, 16); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("Device open failed"); + exit(EXIT_FAILURE); + } + + /* Setup filter */ + hci_filter_clear(&flt); + hci_filter_set_ptype(HCI_EVENT_PKT, &flt); + hci_filter_all_events(&flt); + if (setsockopt(dd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { + perror("HCI filter setup failed"); + exit(EXIT_FAILURE); + } + + printf("< HCI Command: OGF 0x%02x, OCF 0x%04x, plen %d\n", ogf, ocf, len); + hex_dump(" ", 20, buf, len); + fflush(stdout); + + if (hci_send_cmd(dd, ogf, ocf, len, buf) < 0) { + perror("Send failed"); + exit(EXIT_FAILURE); + } + + len = read(dd, buf, sizeof(buf)); + if (len < 0) { + perror("Read failed"); + exit(EXIT_FAILURE); + } + + hdr = (void *)(buf + 1); + ptr = buf + (1 + HCI_EVENT_HDR_SIZE); + len -= (1 + HCI_EVENT_HDR_SIZE); + + printf("> HCI Event: 0x%02x plen %d:\n", hdr->evt, hdr->plen); + hex_dump(" ", 20, ptr, len); + fflush(stdout); + + return; +} + static void cmd_rev(int dev_id, char **opt, int nopt) { if (dev_id < 0) @@ -465,6 +555,7 @@ struct { { "inq", cmd_inq, "[length] [flush]", "Inquire remote devices" }, { "scan", cmd_scan, "[length] [flush]", "Scan for remote devices" }, { "info", cmd_info, "", "Get information from remote device" }, + { "cmd", cmd_cmd, " [param]", "Submit arbitrary HCI commands" }, { "con", cmd_con, 0, "Display active connections" }, { "cc", cmd_cc, " [pkt type] [role]", "Create connection to remote device" }, { "dc", cmd_dc, "", "Disconnect from remote device" }, -- cgit From ba150fb166ed968105942dd97992be83afd4af50 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 19 Apr 2002 16:45:12 +0000 Subject: cmd_cmd cleanup --- tools/hcitool.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index b5256300..96448533 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -156,7 +156,6 @@ static int rev_info(int dev_id, long arg) break; } printf("\n"); - return 0; } @@ -185,8 +184,7 @@ static int conn_list(int dev_id, long arg) printf("\t%s %s %s handle %d state %d lm %s\n", ci->out ? "<" : ">", ci->type == ACL_LINK ? "ACL" : "SCO", - batostr(&bdaddr), ci->handle, - ci->state, + batostr(&bdaddr), ci->handle, ci->state, hci_lmtostr(ci->link_mode)); } return 0; @@ -237,7 +235,7 @@ static void hex_dump(char *pref, int width, unsigned char *buf, int len) static void cmd_dev(int dev_id, char **opt, int nopt) { printf("Devices:\n"); - for_each_dev(HCI_UP, dev_info, 0); + for_each_dev(HCI_UP, dev_info, 0); } static void cmd_inq(int dev_id, char **opt, int nopt) @@ -282,8 +280,8 @@ static void cmd_scan(int dev_id, char **opt, int nopt) inquiry_info *info; int i, num_rsp = 0, length, flags; bdaddr_t bdaddr; - int dd; char name[248]; + int dd; if (dev_id < 0) dev_id = get_route(NULL); @@ -372,7 +370,6 @@ static void cmd_info(int dev_id, char **opt, int nopt) hci_disconnect(dd, handle, 0x13, 10000); close(dd); - } static void cmd_cmd(int dev_id, char **opt, int nopt) @@ -380,9 +377,9 @@ static void cmd_cmd(int dev_id, char **opt, int nopt) char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; struct hci_filter flt; hci_event_hdr *hdr; + int i, len, dd; uint16_t ocf; uint8_t ogf; - int i, len, dd; if (nopt < 2) { usage(); @@ -395,7 +392,7 @@ static void cmd_cmd(int dev_id, char **opt, int nopt) errno = 0; ogf = strtol(opt[0], NULL, 16); ocf = strtol(opt[1], NULL, 16); - if (errno == ERANGE || (ogf > 0x3f) || (htobs(ocf) > 0x3ff)) { + if (errno == ERANGE || (ogf > 0x3f) || (ocf > 0x3ff)) { usage(); return; } @@ -418,9 +415,8 @@ static void cmd_cmd(int dev_id, char **opt, int nopt) exit(EXIT_FAILURE); } - printf("< HCI Command: OGF 0x%02x, OCF 0x%04x, plen %d\n", ogf, ocf, len); - hex_dump(" ", 20, buf, len); - fflush(stdout); + printf("< HCI Command: ogf 0x%02x, ocf 0x%04x, plen %d\n", ogf, ocf, len); + hex_dump(" ", 20, buf, len); fflush(stdout); if (hci_send_cmd(dd, ogf, ocf, len, buf) < 0) { perror("Send failed"); @@ -437,10 +433,10 @@ static void cmd_cmd(int dev_id, char **opt, int nopt) ptr = buf + (1 + HCI_EVENT_HDR_SIZE); len -= (1 + HCI_EVENT_HDR_SIZE); - printf("> HCI Event: 0x%02x plen %d:\n", hdr->evt, hdr->plen); - hex_dump(" ", 20, ptr, len); - fflush(stdout); + printf("> HCI Event: 0x%02x plen %d\n", hdr->evt, hdr->plen); + hex_dump(" ", 20, ptr, len); fflush(stdout); + hci_close_dev(dd); return; } @@ -555,7 +551,7 @@ struct { { "inq", cmd_inq, "[length] [flush]", "Inquire remote devices" }, { "scan", cmd_scan, "[length] [flush]", "Scan for remote devices" }, { "info", cmd_info, "", "Get information from remote device" }, - { "cmd", cmd_cmd, " [param]", "Submit arbitrary HCI commands" }, + { "cmd", cmd_cmd, " [param]", "Submit arbitrary HCI commands" }, { "con", cmd_con, 0, "Display active connections" }, { "cc", cmd_cc, " [pkt type] [role]", "Create connection to remote device" }, { "dc", cmd_dc, "", "Disconnect from remote device" }, -- cgit From 996b96baf78a1e77e94c08f391e00a8bc7822955 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 19 Apr 2002 20:04:13 +0000 Subject: New improved argument processing. --- tools/hcitool.c | 397 ++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 313 insertions(+), 84 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 96448533..35509f22 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -36,6 +36,7 @@ #include #include +#include #include #include #include @@ -48,6 +49,8 @@ extern int optind,opterr,optopt; extern char *optarg; +#define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, NULL)) != -1) + static int ctl; static void usage(void); @@ -232,29 +235,79 @@ static void hex_dump(char *pref, int width, unsigned char *buf, int len) printf("\n"); } -static void cmd_dev(int dev_id, char **opt, int nopt) +/* Display local devices */ + +static struct option dev_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *dev_help = + "Usage:\n" + "\tdev\n"; + +static void cmd_dev(int dev_id, int argc, char **argv) { + int opt; + for_each_opt(opt, dev_options, NULL) { + switch(opt) { + default: + printf(dev_help); + return; + } + } + printf("Devices:\n"); for_each_dev(HCI_UP, dev_info, 0); } -static void cmd_inq(int dev_id, char **opt, int nopt) +/* Inquiry */ + +static struct option inq_options[] = { + {"help", 0,0, 'h'}, + {"length", 1,0, 'l'}, + {"numrsp", 1,0, 'n'}, + {"flush", 0,0, 'f'}, + {0, 0, 0, 0} +}; + +static char *inq_help = + "Usage:\n" + "\tinq [--length=N] [--numrsp=N] [--flush]\n"; + +static void cmd_inq(int dev_id, int argc, char **argv) { + int num_rsp, length, flags; inquiry_info *info; - int i, num_rsp = 0, length, flags; bdaddr_t bdaddr; - - if (dev_id < 0) - dev_id = get_route(NULL); - - if (nopt >= 1) - length = atoi(opt[0]); - else - length = 8; /* ~ 10 seconds */ + int i, opt; + length = 8; /* ~10 seconds */ + num_rsp = 10; flags = 0; - if (nopt >= 2) - flags |= !strncasecmp("f", opt[1], 1) ? IREQ_CACHE_FLUSH : 0; + + for_each_opt(opt, inq_options, NULL) { + switch(opt) { + case 'l': + length = atoi(optarg); + break; + + case 'n': + num_rsp = atoi(optarg); + break; + + case 'f': + flags |= IREQ_CACHE_FLUSH; + break; + + default: + printf(inq_help); + return; + } + } + + if (dev_id < 0) + dev_id = get_route(NULL); printf("Inquiring ...\n"); info = hci_inquiry(dev_id, length, &num_rsp, NULL, flags); @@ -275,25 +328,54 @@ static void cmd_inq(int dev_id, char **opt, int nopt) free(info); } -static void cmd_scan(int dev_id, char **opt, int nopt) +/* Device scanning */ + +static struct option scan_options[] = { + {"help", 0,0, 'h'}, + {"length", 1,0, 'l'}, + {"numrsp", 1,0, 'n'}, + {"flush", 0,0, 'f'}, + {0, 0, 0, 0} +}; + +static char *scan_help = + "Usage:\n" + "\tscan [--length=N] [--numrsp=N] [--flush]\n"; + +static void cmd_scan(int dev_id, int argc, char **argv) { inquiry_info *info; - int i, num_rsp = 0, length, flags; + int num_rsp, length, flags; bdaddr_t bdaddr; char name[248]; - int dd; + int i, opt, dd; - if (dev_id < 0) - dev_id = get_route(NULL); + length = 8; /* ~10 seconds */ + num_rsp = 10; + flags = 0; - if (nopt >= 1) - length = atoi(opt[0]); - else - length = 8; /* ~ 10 seconds */ + for_each_opt(opt, scan_options, NULL) { + switch(opt) { + case 'l': + length = atoi(optarg); + break; + + case 'n': + num_rsp = atoi(optarg); + break; - flags = 0; - if (nopt >= 2) - flags |= !strncasecmp("f", opt[1], 1) ? IREQ_CACHE_FLUSH : 0; + case 'f': + flags |= IREQ_CACHE_FLUSH; + break; + + default: + printf(scan_help); + return; + } + } + + if (dev_id < 0) + dev_id = get_route(NULL); printf("Scanning ...\n"); info = hci_inquiry(dev_id, length, &num_rsp, NULL, flags); @@ -315,19 +397,42 @@ static void cmd_scan(int dev_id, char **opt, int nopt) free(info); } -static void cmd_info(int dev_id, char **opt, int nopt) +/* Info about remote device */ + +static struct option info_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *info_help = + "Usage:\n" + "\tinfo \n"; + +static void cmd_info(int dev_id, int argc, char **argv) { bdaddr_t bdaddr; uint16_t handle; - int dd; char name[248]; unsigned char features[8]; struct hci_version version; + int opt, dd; + + for_each_opt(opt, info_options, NULL) { + switch(opt) { + default: + printf(info_help); + return; + } + } + argc -= optind; + argv += optind; - if (nopt < 1) + if (argc < 1) { + printf(info_help); return; + } - baswap(&bdaddr, strtoba(opt[0])); + baswap(&bdaddr, strtoba(argv[0])); if (dev_id < 0) { dev_id = get_route(&bdaddr); @@ -345,7 +450,7 @@ static void cmd_info(int dev_id, char **opt, int nopt) exit(1); } - printf("\tBD Address: %s\n", opt[0]); + printf("\tBD Address: %s\n", argv[0]); if (hci_create_connection(dd, &bdaddr, 0x0008 | 0x0010, 0, 0, &handle, 25000) < 0) { close(dd); @@ -372,17 +477,40 @@ static void cmd_info(int dev_id, char **opt, int nopt) close(dd); } -static void cmd_cmd(int dev_id, char **opt, int nopt) +/* Send arbitrary HCI commands */ + +static struct option cmd_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *cmd_help = + "Usage:\n" + "\tcmd [parameters]\n" + "Example:\n" + "\tcmd 0x03 0x0013 0x41 0x42 0x43 0x44\n"; + +static void cmd_cmd(int dev_id, int argc, char **argv) { char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; struct hci_filter flt; hci_event_hdr *hdr; - int i, len, dd; + int i, opt, len, dd; uint16_t ocf; uint8_t ogf; - if (nopt < 2) { - usage(); + for_each_opt(opt, cmd_options, NULL) { + switch(opt) { + default: + printf(cmd_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 2) { + printf(cmd_help); return; } @@ -390,15 +518,15 @@ static void cmd_cmd(int dev_id, char **opt, int nopt) dev_id = get_route(NULL); errno = 0; - ogf = strtol(opt[0], NULL, 16); - ocf = strtol(opt[1], NULL, 16); + ogf = strtol(argv[0], NULL, 16); + ocf = strtol(argv[1], NULL, 16); if (errno == ERANGE || (ogf > 0x3f) || (ocf > 0x3ff)) { - usage(); + printf(cmd_help); return; } - for (i = 2, len = 0; i < nopt && len < sizeof(buf); i++, len++) - *ptr++ = (uint8_t) strtol(opt[i], NULL, 16); + for (i = 2, len = 0; i < argc && len < sizeof(buf); i++, len++) + *ptr++ = (uint8_t) strtol(argv[i], NULL, 16); dd = hci_open_dev(dev_id); if (dd < 0) { @@ -440,16 +568,58 @@ static void cmd_cmd(int dev_id, char **opt, int nopt) return; } -static void cmd_rev(int dev_id, char **opt, int nopt) +/* Display revision info */ + +static struct option rev_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *rev_help = + "Usage:\n" + "\trev\n"; + +static void cmd_rev(int dev_id, int argc, char **argv) { + int opt; + + for_each_opt(opt, rev_options, NULL) { + switch(opt) { + default: + printf(rev_help); + return; + } + } + if (dev_id < 0) for_each_dev(HCI_UP, rev_info, 0); else rev_info(dev_id, 0); } -static void cmd_con(int dev_id, char **opt, int nopt) +/* Display active connections */ + +static struct option con_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *con_help = + "Usage:\n" + "\tcon\n"; + +static void cmd_con(int dev_id, int argc, char **argv) { + int opt; + + for_each_opt(opt, con_options, NULL) { + switch(opt) { + default: + printf(con_help); + return; + } + } + printf("Connections:\n"); if (dev_id < 0) for_each_dev(HCI_UP, conn_list, 0); @@ -457,17 +627,56 @@ static void cmd_con(int dev_id, char **opt, int nopt) conn_list(dev_id, 0); } -static void cmd_cc(int dev_id, char **opt, int nopt) +/* Create connection */ + +static struct option cc_options[] = { + {"help", 0,0, 'h'}, + {"role", 1,0, 'r'}, + {"ptype", 1,0, 'p'}, + {0, 0, 0, 0} +}; + +static char *cc_help = + "Usage:\n" + "\tcc [--role=m|s] [--ptype=pkt_types] \n" + "Example:\n" + "\tcc --ptype=dm1,dh3,dh5 01:02:03:04:05:06\n" + "\tcc --role=m 01:02:03:04:05:06\n"; + +static void cmd_cc(int dev_id, int argc, char **argv) { bdaddr_t bdaddr; - int ptype, dd; + int opt, ptype, dd; uint16_t handle; uint8_t role; - if (nopt < 1) + role = 0; + ptype = HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5; + + for_each_opt(opt, cc_options, NULL) { + switch(opt) { + case 'p': + hci_strtoptype(optarg, &ptype); + break; + + case 'r': + role = optarg[0] == 'm' ? 0 : 1; + break; + + default: + printf(cc_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(cc_help); return; + } - baswap(&bdaddr, strtoba(opt[0])); + str2ba(argv[0], &bdaddr); if (dev_id < 0) { dev_id = get_route(&bdaddr); @@ -483,31 +692,43 @@ static void cmd_cc(int dev_id, char **opt, int nopt) exit(1); } - if (nopt >= 2) - hci_strtoptype(opt[1], &ptype); - else - ptype = HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5; - - if (nopt >= 3) - role = !strncasecmp("m", opt[2], 1) ? 0 : 1; - else - role = 0; - hci_create_connection(dd, &bdaddr, ptype, 0, role, &handle, 1000); - hci_close_dev(dd); } -static void cmd_dc(int dev_id, char **opt, int nopt) +/* Close connection */ + +static struct option dc_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *dc_help = + "Usage:\n" + "\tdc \n"; + +static void cmd_dc(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; bdaddr_t bdaddr; - int dd; + int opt, dd; + + for_each_opt(opt, dc_options, NULL) { + switch(opt) { + default: + printf(dc_help); + return; + } + } + argc -= optind; + argv += optind; - if (nopt < 1) + if (argc < 1) { + printf(dc_help); return; + } - baswap(&bdaddr, strtoba(*opt)); + str2ba(argv[0], &bdaddr); if (dev_id < 0) { dev_id = for_each_dev(HCI_UP, find_conn, (long) &bdaddr); @@ -542,19 +763,18 @@ static void cmd_dc(int dev_id, char **opt, int nopt) struct { char *cmd; - void (*func)(int dev_id, char **opt, int nopt); - char *opt; + void (*func)(int dev_id, int argc, char **argv); char *doc; } command[] = { - { "dev", cmd_dev, 0, "Display local devices" }, - { "rev", cmd_rev, 0, "Display revison information" }, - { "inq", cmd_inq, "[length] [flush]", "Inquire remote devices" }, - { "scan", cmd_scan, "[length] [flush]", "Scan for remote devices" }, - { "info", cmd_info, "", "Get information from remote device" }, - { "cmd", cmd_cmd, " [param]", "Submit arbitrary HCI commands" }, - { "con", cmd_con, 0, "Display active connections" }, - { "cc", cmd_cc, " [pkt type] [role]", "Create connection to remote device" }, - { "dc", cmd_dc, "", "Disconnect from remote device" }, + { "dev", cmd_dev, "Display local devices" }, + { "rev", cmd_rev, "Display revison information" }, + { "inq", cmd_inq, "Inquire remote devices" }, + { "scan", cmd_scan, "Scan for remote devices" }, + { "info", cmd_info, "Get information from remote device" }, + { "cmd", cmd_cmd, "Submit arbitrary HCI commands" }, + { "con", cmd_con, "Display active connections" }, + { "cc", cmd_cc, "Create connection to remote device" }, + { "dc", cmd_dc, "Disconnect from remote device" }, { NULL, NULL, 0} }; @@ -564,24 +784,30 @@ static void usage(void) printf("hcitool - HCI Tool\n"); printf("Usage:\n" - "\thcitool [-i hciX] [command]\n"); + "\thcitool [options] [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 %-20s\t%s\n", command[i].cmd, - command[i].opt ? command[i].opt : " ", + printf("\t%-4s\t%s\n", command[i].cmd, command[i].doc); } -int main(int argc, char *argv[], char *env[]) +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; - char *dev; - while ((opt=getopt(argc, argv, "i:h")) != EOF) { + while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { switch(opt) { case 'i': - dev = strdup(optarg); - dev_id = atoi(dev + 3); + dev_id = atoi(optarg + 3); break; case 'h': @@ -591,22 +817,25 @@ int main(int argc, char *argv[], char *env[]) } } - if (argc - optind < 1) { + argc -= optind; + argv += optind; + optind = 0; + + if (argc < 1) { usage(); exit(0); } - /* Open HCI socket */ + /* Open HCI socket */ if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) { perror("Can't open HCI socket."); exit(1); } for (i=0; command[i].cmd; i++) { - if (strncmp(command[i].cmd, argv[optind], 3)) + if (strncmp(command[i].cmd, argv[0], 3)) continue; - optind++; - command[i].func(dev_id, argv + optind, argc - optind); + command[i].func(dev_id, argc, argv); break; } -- cgit From 98f6f92be002a098fb4f3b773939ab7c94834a0d Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 22 Apr 2002 20:16:27 +0000 Subject: Display feature bytes in hex --- tools/hcitool.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 35509f22..06c426ca 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -468,7 +468,8 @@ static void cmd_info(int dev_id, int argc, char **argv) } if (hci_read_remote_features(dd, handle, features, 20000) == 0) { - printf("\tFeatures:\n%s\n", + printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n%s\n", + features[0], features[1], features[2], features[3], lmp_featurestostr(features, "\t\t", 3)); } -- cgit From d65d0510cd20a55a08b64f476714b229c5436396 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 22 Apr 2002 20:43:10 +0000 Subject: Argument parsing fixes --- tools/hcitool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 06c426ca..8ec564d7 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -783,7 +783,7 @@ static void usage(void) { int i; - printf("hcitool - HCI Tool\n"); + printf("hcitool - HCI Tool ver %s\n", VERSION); printf("Usage:\n" "\thcitool [options] [command parameters]\n"); printf("Options:\n" -- cgit From 095e2ef25275e4682b9c1a51d6f9f233f0360d18 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 2 May 2002 20:54:47 +0000 Subject: Added "name" command. --- tools/hcitool.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 8ec564d7..f6a98610 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -397,6 +397,61 @@ static void cmd_scan(int dev_id, int argc, char **argv) free(info); } +/* Remote name */ + +static struct option name_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *name_help = + "Usage:\n" + "\tname \n"; + +static void cmd_name(int dev_id, int argc, char **argv) +{ + bdaddr_t bdaddr; + char name[248]; + int opt, dd; + + for_each_opt(opt, name_options, NULL) { + switch(opt) { + default: + printf(name_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(name_help); + return; + } + + baswap(&bdaddr, strtoba(argv[0])); + + if (dev_id < 0) { + dev_id = get_route(&bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Device is not available.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + if (hci_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0) + printf("%s\n", name); + + close(dd); + +} + /* Info about remote device */ static struct option info_options[] = { @@ -771,6 +826,7 @@ struct { { "rev", cmd_rev, "Display revison information" }, { "inq", cmd_inq, "Inquire remote devices" }, { "scan", cmd_scan, "Scan for remote devices" }, + { "name", cmd_name, "Get name from remote device" }, { "info", cmd_info, "Get information from remote device" }, { "cmd", cmd_cmd, "Submit arbitrary HCI commands" }, { "con", cmd_con, "Display active connections" }, -- cgit From 6446efe312e0410efc4c45dc68f5d980755f0666 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Wed, 8 May 2002 17:00:05 +0000 Subject: Use hci_test_bit instead of (1<dev_num; i++, dr++) { - if (dr->dev_opt & (1<dev_opt)) { if (!func || func(dr->dev_id, arg)) return dr->dev_id; } -- cgit From c1df5fbb4f48cfdd3cd4a566a0836889aa6e8458 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Wed, 8 May 2002 17:41:10 +0000 Subject: RSSI support. --- tools/hcitool.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 68d4aa7a..5ac90657 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -817,6 +817,91 @@ static void cmd_dc(int dev_id, int argc, char **argv) free(cr); } +/* Read RSSI */ + +static struct option rssi_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *rssi_help = + "Usage:\n" + "\trssi \n"; + +static void cmd_rssi(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + struct hci_request rq; + read_rssi_rp rp; + bdaddr_t bdaddr; + int opt, dd; + + for_each_opt(opt, rssi_options, NULL) { + switch(opt) { + default: + printf(rssi_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(rssi_help); + return; + } + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + rq.ogf = OGF_STATUS_PARAM; + rq.ocf = OCF_READ_RSSI; + rq.cparam = &cr->conn_info->handle; + rq.clen = 2; + rq.rparam = &rp; + rq.rlen = READ_RSSI_RP_SIZE; + + if (hci_send_req(dd, &rq, 100) < 0) { + printf("Can't read RSSI hci%d. %s(%d)\n", + dd, strerror(errno), errno); + exit(1); + } + + if (rp.status) { + printf("Read RSSI on hci%d returned (error) status 0x%2.2X\n", + dd, rp.status); + exit(1); + } + printf( "\tRSSI return value: %d\n", rp.rssi); + + close(dd); + free(cr); +} + struct { char *cmd; void (*func)(int dev_id, int argc, char **argv); @@ -832,6 +917,7 @@ struct { { "con", cmd_con, "Display active connections" }, { "cc", cmd_cc, "Create connection to remote device" }, { "dc", cmd_dc, "Disconnect from remote device" }, + { "rssi", cmd_rssi, "Display connection RSSI" }, { NULL, NULL, 0} }; -- cgit From 8f32a0237d9eae5ab56916424bb1e7580be28db1 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 13 May 2002 18:55:25 +0000 Subject: usage clarification --- tools/hcitool.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 5ac90657..67cd7987 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -935,6 +935,9 @@ static void usage(void) 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" + "\thcitool --help\n" ); } static struct option main_options[] = { -- cgit From b9d072d8c187426e925356dc5fdc143f6a19d4bb Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Sat, 18 May 2002 00:50:26 +0000 Subject: Change connection packet type support. --- tools/hcitool.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 86 insertions(+), 5 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 67cd7987..7f7cf1de 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -878,6 +878,7 @@ static void cmd_rssi(int dev_id, int argc, char **argv) exit(1); } + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_STATUS_PARAM; rq.ocf = OCF_READ_RSSI; rq.cparam = &cr->conn_info->handle; @@ -886,22 +887,101 @@ static void cmd_rssi(int dev_id, int argc, char **argv) rq.rlen = READ_RSSI_RP_SIZE; if (hci_send_req(dd, &rq, 100) < 0) { - printf("Can't read RSSI hci%d. %s(%d)\n", - dd, strerror(errno), errno); + perror("Read RSSI failed"); exit(1); } if (rp.status) { - printf("Read RSSI on hci%d returned (error) status 0x%2.2X\n", - dd, rp.status); + printf("Read RSSI returned (error) status 0x%2.2X\n", rp.status); exit(1); } - printf( "\tRSSI return value: %d\n", rp.rssi); + printf("\tRSSI return value: %d\n", rp.rssi); close(dd); free(cr); } +/* Set connection packet type */ + +static struct option cpt_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *cpt_help = + "Usage:\n" + "\tcpt \n"; + +static void cmd_cpt(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + struct hci_request rq; + set_conn_ptype_cp cp; + bdaddr_t bdaddr; + int opt, dd, ptype; + + for_each_opt(opt, cpt_options, NULL) { + switch(opt) { + default: + printf(cpt_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 2) { + printf(cpt_help); + return; + } + + str2ba(argv[0], &bdaddr); + hci_strtoptype(argv[1], &ptype); + + if (dev_id < 0) { + dev_id = for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + cp.handle = cr->conn_info->handle; + cp.pkt_type = ptype; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_STATUS_PARAM; + rq.ocf = OCF_READ_RSSI; + rq.cparam = &cp; + rq.clen = SET_CONN_PTYPE_CP_SIZE; + + if (hci_send_req(dd, &rq, 100) < 0) { + perror("Packet type change failed"); + exit(1); + } + + close(dd); + free(cr); +} + + struct { char *cmd; void (*func)(int dev_id, int argc, char **argv); @@ -917,6 +997,7 @@ struct { { "con", cmd_con, "Display active connections" }, { "cc", cmd_cc, "Create connection to remote device" }, { "dc", cmd_dc, "Disconnect from remote device" }, + { "cpt", cmd_cpt, "Change connection packet type" }, { "rssi", cmd_rssi, "Display connection RSSI" }, { NULL, NULL, 0} }; -- cgit From d8ab2999e595a6cf7e853c881d1716c7262fe74a Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 23 May 2002 20:56:51 +0000 Subject: help output improvements --- tools/hcitool.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 7f7cf1de..8ce64ed6 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -273,7 +273,9 @@ static struct option inq_options[] = { static char *inq_help = "Usage:\n" - "\tinq [--length=N] [--numrsp=N] [--flush]\n"; + "\tinq [--length=N] maximum inquiry duration in 1.28 s units\n" + "\t [--numrsp=N] specify maximum number of inquiry responses\n" + "\t [--flush] flush the inquiry cache\n"; static void cmd_inq(int dev_id, int argc, char **argv) { -- cgit From 8ee2371d4b948a541a71fce00e1cfde01ed364d8 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 18 Jun 2002 16:48:50 +0000 Subject: Use library functions hci_for_each_dev and hci_get_route. Use new hci_inquiry function syntax. --- tools/hcitool.c | 125 +++++++++++++++----------------------------------------- 1 file changed, 33 insertions(+), 92 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 8ce64ed6..c2ad6186 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -51,62 +51,13 @@ extern char *optarg; #define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, NULL)) != -1) -static int ctl; - static void usage(void); -static int for_each_dev(int flag, int(*func)(int d, long arg), long arg) -{ - struct hci_dev_list_req *dl; - struct hci_dev_req *dr; - int i; - - dl = malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t)); - if (!dl) { - perror("Can't allocate memory"); - return -1; - } - dl->dev_num = HCI_MAX_DEV; - dr = dl->dev_req; - - if (ioctl(ctl, HCIGETDEVLIST, (void*)dl)) { - perror("Can't get device list"); - return -1; - } - - if (!dl->dev_num) - return -1; - - for (i=0; i < dl->dev_num; i++, dr++) { - if (hci_test_bit(flag, &dr->dev_opt)) { - if (!func || func(dr->dev_id, arg)) - return dr->dev_id; - } - } - return -1; -} - -static int other_bdaddr(int dev_id, long arg) -{ - struct hci_dev_info di = {dev_id: dev_id}; - if (ioctl(ctl, HCIGETDEVINFO, (void*) &di)) - return 0; - return bacmp((bdaddr_t *)arg, &di.bdaddr); -} - -static int get_route(bdaddr_t *bdaddr) -{ - if (bdaddr) - return for_each_dev(HCI_UP, other_bdaddr, (long) bdaddr); - else - return for_each_dev(HCI_UP, NULL, 0); -} - -static int dev_info(int dev_id, long arg) +static int dev_info(int s, int dev_id, long arg) { struct hci_dev_info di = {dev_id: dev_id}; bdaddr_t bdaddr; - if (ioctl(ctl, HCIGETDEVINFO, (void*) &di)) + if (ioctl(s, HCIGETDEVINFO, (void*) &di)) return 0; baswap(&bdaddr, &di.bdaddr); @@ -114,14 +65,17 @@ static int dev_info(int dev_id, long arg) return 0; } -static int rev_info(int dev_id, long arg) +static int rev_info(int s, int dev_id, long arg) { struct hci_version ver; + int id = arg; int dd; struct hci_request rq; unsigned char buf[102]; + if (id != -1 && dev_id != id) + return 0; dd = hci_open_dev(dev_id); if (dd < 0) { @@ -162,12 +116,16 @@ static int rev_info(int dev_id, long arg) return 0; } -static int conn_list(int dev_id, long arg) +static int conn_list(int s, int dev_id, long arg) { struct hci_conn_list_req *cl; struct hci_conn_info *ci; + int id = arg; int i; + if (id != -1 && dev_id != id) + return 0; + if (!(cl = malloc(10 * sizeof(*ci) + sizeof(*cl)))) { perror("Can't allocate memory"); exit(1); @@ -176,7 +134,7 @@ static int conn_list(int dev_id, long arg) cl->conn_num = 10; ci = cl->conn_info; - if (ioctl(ctl, HCIGETCONNLIST, (void*)cl)) { + if (ioctl(s, HCIGETCONNLIST, (void*)cl)) { perror("Can't get connection list"); exit(1); } @@ -193,7 +151,7 @@ static int conn_list(int dev_id, long arg) return 0; } -static int find_conn(int dev_id, long arg) +static int find_conn(int s, int dev_id, long arg) { struct hci_conn_list_req *cl; struct hci_conn_info *ci; @@ -207,7 +165,7 @@ static int find_conn(int dev_id, long arg) cl->conn_num = 10; ci = cl->conn_info; - if (ioctl(ctl, HCIGETCONNLIST, (void*)cl)) { + if (ioctl(s, HCIGETCONNLIST, (void*)cl)) { perror("Can't get connection list"); exit(1); } @@ -258,7 +216,7 @@ static void cmd_dev(int dev_id, int argc, char **argv) } printf("Devices:\n"); - for_each_dev(HCI_UP, dev_info, 0); + hci_for_each_dev(HCI_UP, dev_info, 0); } /* Inquiry */ @@ -280,7 +238,7 @@ static char *inq_help = static void cmd_inq(int dev_id, int argc, char **argv) { int num_rsp, length, flags; - inquiry_info *info; + inquiry_info *info = NULL; bdaddr_t bdaddr; int i, opt; @@ -308,13 +266,9 @@ static void cmd_inq(int dev_id, int argc, char **argv) } } - if (dev_id < 0) - dev_id = get_route(NULL); - printf("Inquiring ...\n"); - info = hci_inquiry(dev_id, length, &num_rsp, NULL, flags); - - if (!info) { + num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); + if (num_rsp < 0) { perror("Inquiry failed."); exit(1); } @@ -346,7 +300,7 @@ static char *scan_help = static void cmd_scan(int dev_id, int argc, char **argv) { - inquiry_info *info; + inquiry_info *info = NULL; int num_rsp, length, flags; bdaddr_t bdaddr; char name[248]; @@ -376,13 +330,9 @@ static void cmd_scan(int dev_id, int argc, char **argv) } } - if (dev_id < 0) - dev_id = get_route(NULL); - printf("Scanning ...\n"); - info = hci_inquiry(dev_id, length, &num_rsp, NULL, flags); - - if (!info) { + num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); + if (num_rsp < 0) { perror("Inquiry failed."); exit(1); } @@ -434,7 +384,7 @@ static void cmd_name(int dev_id, int argc, char **argv) baswap(&bdaddr, strtoba(argv[0])); if (dev_id < 0) { - dev_id = get_route(&bdaddr); + dev_id = hci_get_route(&bdaddr); if (dev_id < 0) { fprintf(stderr, "Device is not available.\n"); exit(1); @@ -492,7 +442,7 @@ static void cmd_info(int dev_id, int argc, char **argv) baswap(&bdaddr, strtoba(argv[0])); if (dev_id < 0) { - dev_id = get_route(&bdaddr); + dev_id = hci_get_route(&bdaddr); if (dev_id < 0) { fprintf(stderr, "Device is not available.\n"); exit(1); @@ -573,7 +523,7 @@ static void cmd_cmd(int dev_id, int argc, char **argv) } if (dev_id < 0) - dev_id = get_route(NULL); + dev_id = hci_get_route(NULL); errno = 0; ogf = strtol(argv[0], NULL, 16); @@ -648,11 +598,7 @@ static void cmd_rev(int dev_id, int argc, char **argv) return; } } - - if (dev_id < 0) - for_each_dev(HCI_UP, rev_info, 0); - else - rev_info(dev_id, 0); + hci_for_each_dev(HCI_UP, rev_info, dev_id); } /* Display active connections */ @@ -679,10 +625,7 @@ static void cmd_con(int dev_id, int argc, char **argv) } printf("Connections:\n"); - if (dev_id < 0) - for_each_dev(HCI_UP, conn_list, 0); - else - conn_list(dev_id, 0); + hci_for_each_dev(HCI_UP, conn_list, dev_id); } /* Create connection */ @@ -737,7 +680,7 @@ static void cmd_cc(int dev_id, int argc, char **argv) str2ba(argv[0], &bdaddr); if (dev_id < 0) { - dev_id = get_route(&bdaddr); + dev_id = hci_get_route(&bdaddr); if (dev_id < 0) { fprintf(stderr, "Device is not available.\n"); exit(1); @@ -789,7 +732,7 @@ static void cmd_dc(int dev_id, int argc, char **argv) str2ba(argv[0], &bdaddr); if (dev_id < 0) { - dev_id = for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); if (dev_id < 0) { fprintf(stderr, "Not connected.\n"); exit(1); @@ -856,7 +799,7 @@ static void cmd_rssi(int dev_id, int argc, char **argv) str2ba(argv[0], &bdaddr); if (dev_id < 0) { - dev_id = for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); if (dev_id < 0) { fprintf(stderr, "Not connected.\n"); exit(1); @@ -941,7 +884,7 @@ static void cmd_cpt(int dev_id, int argc, char **argv) hci_strtoptype(argv[1], &ptype); if (dev_id < 0) { - dev_id = for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); if (dev_id < 0) { fprintf(stderr, "Not connected.\n"); exit(1); @@ -1032,6 +975,7 @@ static struct option main_options[] = { 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) { @@ -1055,9 +999,8 @@ int main(int argc, char **argv) exit(0); } - /* Open HCI socket */ - if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) { - perror("Can't open HCI socket."); + if (dev_id != -1 && hci_devba(dev_id, &ba) < 0) { + perror("Device is not available"); exit(1); } @@ -1067,7 +1010,5 @@ int main(int argc, char **argv) command[i].func(dev_id, argc, argv); break; } - - close(ctl); return 0; } -- cgit From 002edf82ee25e3161bb00e6c976aefcb11062ba1 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 18 Jun 2002 18:33:43 +0000 Subject: use hci_devid --- tools/hcitool.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index c2ad6186..96348342 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -980,7 +980,11 @@ int main(int argc, char **argv) while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { switch(opt) { case 'i': - dev_id = atoi(optarg + 3); + dev_id = hci_devid(optarg); + if (dev_id < 0) { + perror("Invalid device"); + exit(1); + } break; case 'h': -- cgit From 596c0840d5682ccae5f1805f92f32391608bfac8 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 20 Jun 2002 00:24:30 +0000 Subject: scan command works again. --- tools/hcitool.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 96348342..ae03ee96 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -330,6 +330,14 @@ static void cmd_scan(int dev_id, int argc, char **argv) } } + if (dev_id < 0) { + dev_id = hci_get_route(&bdaddr); + if (dev_id < 0) { + perror("Device is not available."); + exit(1); + } + } + printf("Scanning ...\n"); num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); if (num_rsp < 0) { @@ -337,15 +345,22 @@ static void cmd_scan(int dev_id, int argc, char **argv) exit(1); } + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + free(info); + exit(1); + } + for (i = 0; i < num_rsp; i++) { - dd = hci_open_dev(dev_id); memset(name, 0, sizeof(name)); if (hci_remote_name(dd, &(info+i)->bdaddr, sizeof(name), name, 100000) < 0) strcpy(name, "n/a"); - close(dd); baswap(&bdaddr, &(info+i)->bdaddr); - printf("\t%s\t%s\n", batostr(&bdaddr), name); + printf("\t%s\t%s\n", batostr(&bdaddr), name); } + + close(dd); free(info); } -- cgit From aaa64a3108d3bb8eba3e49f2b58d3909627bbca0 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 25 Jun 2002 04:36:09 +0000 Subject: Move revision command to hciconfig. --- tools/hcitool.c | 77 --------------------------------------------------------- 1 file changed, 77 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index ae03ee96..8eaa2cc2 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -65,57 +65,6 @@ static int dev_info(int s, int dev_id, long arg) return 0; } -static int rev_info(int s, int dev_id, long arg) -{ - struct hci_version ver; - int id = arg; - int dd; - - struct hci_request rq; - unsigned char buf[102]; - - if (id != -1 && dev_id != id) - return 0; - - dd = hci_open_dev(dev_id); - if (dd < 0) { - printf("Can't open device hci%d. %s(%d)\n", dev_id, strerror(errno), errno); - return -1; - } - - if (hci_read_local_version(dd, &ver, 1000) < 0) { - printf("Can't read version info hci%d. %s(%d)\n", - dev_id, strerror(errno), errno); - return -1; - } - - printf("hci%d:", dev_id); - switch (ver.manufacturer) { - case 0: - memset(&rq, 0, sizeof(rq)); - rq.ogf = 0x3f; - rq.ocf = 0x000f; - rq.cparam = NULL; - rq.clen = 0; - rq.rparam = &buf; - rq.rlen = sizeof(buf); - - if (hci_send_req(dd, &rq, 1000) < 0) { - printf("\n Can't read revision info. %s(%d)\n", - strerror(errno), errno); - return -1; - } - - printf("%s\n", buf + 1); - break; - default: - printf("\n Manufacturer not supported\n"); - break; - } - printf("\n"); - return 0; -} - static int conn_list(int s, int dev_id, long arg) { struct hci_conn_list_req *cl; @@ -591,31 +540,6 @@ static void cmd_cmd(int dev_id, int argc, char **argv) return; } -/* Display revision info */ - -static struct option rev_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} -}; - -static char *rev_help = - "Usage:\n" - "\trev\n"; - -static void cmd_rev(int dev_id, int argc, char **argv) -{ - int opt; - - for_each_opt(opt, rev_options, NULL) { - switch(opt) { - default: - printf(rev_help); - return; - } - } - hci_for_each_dev(HCI_UP, rev_info, dev_id); -} - /* Display active connections */ static struct option con_options[] = { @@ -948,7 +872,6 @@ struct { char *doc; } command[] = { { "dev", cmd_dev, "Display local devices" }, - { "rev", cmd_rev, "Display revison information" }, { "inq", cmd_inq, "Inquire remote devices" }, { "scan", cmd_scan, "Scan for remote devices" }, { "name", cmd_name, "Get name from remote device" }, -- cgit From 04c8ddd5a5d720e75144755d071e2331c979d1ed Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 20 Aug 2002 04:39:54 +0000 Subject: Add 'bluetooth/' to includes --- tools/hcitool.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 8eaa2cc2..7d3772bb 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -42,9 +42,9 @@ #include #include -#include -#include -#include +#include +#include +#include extern int optind,opterr,optopt; extern char *optarg; -- cgit From d10423ecaa32884c2c382756d502f615349c400b Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 22 Aug 2002 10:06:55 +0000 Subject: use hci lib --- tools/hcitool.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 7d3772bb..34a9f5a4 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -303,7 +303,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) for (i = 0; i < num_rsp; i++) { memset(name, 0, sizeof(name)); - if (hci_remote_name(dd, &(info+i)->bdaddr, sizeof(name), name, 100000) < 0) + if (hci_read_remote_name(dd, &(info+i)->bdaddr, sizeof(name), name, 100000) < 0) strcpy(name, "n/a"); baswap(&bdaddr, &(info+i)->bdaddr); printf("\t%s\t%s\n", batostr(&bdaddr), name); @@ -361,7 +361,7 @@ static void cmd_name(int dev_id, int argc, char **argv) exit(1); } - if (hci_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0) + if (hci_read_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0) printf("%s\n", name); close(dd); @@ -428,7 +428,7 @@ static void cmd_info(int dev_id, int argc, char **argv) exit(1); } - if (hci_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0) + if (hci_read_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0) printf("\tDevice Name: %s\n", name); if (hci_read_remote_version(dd, handle, &version, 20000) == 0) { -- cgit From 8f511c20f7f6b0b59316bdb84ff444ccbc918242 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Sun, 15 Sep 2002 17:13:40 +0000 Subject: get link quality support --- tools/hcitool.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 34a9f5a4..730605db 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -785,6 +785,91 @@ static void cmd_rssi(int dev_id, int argc, char **argv) free(cr); } +/* Get Link Quality */ + +static struct option link_quality_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *link_quality_help = + "Usage:\n" + "\tlq \n"; + +static void cmd_link_quality(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + struct hci_request rq; + get_link_quality_rp rp; + bdaddr_t bdaddr; + int opt, dd; + + for_each_opt(opt, link_quality_options, NULL) { + switch(opt) { + default: + printf(link_quality_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(link_quality_help); + return; + } + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_STATUS_PARAM; + rq.ocf = OCF_GET_LINK_QUALITY; + rq.cparam = &cr->conn_info->handle; + rq.clen = 2; + rq.rparam = &rp; + rq.rlen = GET_LINK_QUALITY_RP_SIZE; + + if (hci_send_req(dd, &rq, 100) < 0) { + perror("HCI get_link_quality request failed"); + exit(1); + } + + if (rp.status) { + fprintf(stderr, "HCI get_link_quality cmd failed (0x%2.2X)\n", + rp.status); + exit(1); + } + printf("Link quality: %d\n", rp.link_quality); + + close(dd); + free(cr); +} + /* Set connection packet type */ static struct option cpt_options[] = { @@ -865,7 +950,6 @@ static void cmd_cpt(int dev_id, int argc, char **argv) free(cr); } - struct { char *cmd; void (*func)(int dev_id, int argc, char **argv); @@ -882,6 +966,7 @@ struct { { "dc", cmd_dc, "Disconnect from remote device" }, { "cpt", cmd_cpt, "Change connection packet type" }, { "rssi", cmd_rssi, "Display connection RSSI" }, + { "lq", cmd_link_quality, "Display link quality" }, { NULL, NULL, 0} }; -- cgit From 8c6e7af8ac997ce101009569e3bdaee231e8fb12 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 7 Oct 2002 05:55:21 +0000 Subject: Add for get/set link supervision timeout. --- tools/hcitool.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 114 insertions(+), 2 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 730605db..ec6f007a 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -886,6 +886,7 @@ static void cmd_cpt(int dev_id, int argc, char **argv) struct hci_conn_info_req *cr; struct hci_request rq; set_conn_ptype_cp cp; + evt_conn_ptype_changed rp; bdaddr_t bdaddr; int opt, dd, ptype; @@ -936,10 +937,13 @@ static void cmd_cpt(int dev_id, int argc, char **argv) cp.pkt_type = ptype; memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_STATUS_PARAM; - rq.ocf = OCF_READ_RSSI; + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_SET_CONN_PTYPE; rq.cparam = &cp; rq.clen = SET_CONN_PTYPE_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_CONN_PTYPE_CHANGED_SIZE; + rq.event = EVT_CONN_PTYPE_CHANGED; if (hci_send_req(dd, &rq, 100) < 0) { perror("Packet type change failed"); @@ -950,6 +954,113 @@ static void cmd_cpt(int dev_id, int argc, char **argv) free(cr); } +/* Get/Set Link Supervision Timeout */ + +static struct option link_supervision_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *link_supervision_help = + "Usage:\n" + "\tlst [new value in slots]\n"; + +static void cmd_link_sup_to(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + struct hci_request rq; + read_link_supervision_timeout_rp rp; + write_link_supervision_timeout_cp cp; + bdaddr_t bdaddr; + int opt, dd; + + for_each_opt(opt, link_supervision_options, NULL) { + switch(opt) { + default: + printf(link_supervision_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(link_supervision_help); + return; + } + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + if (argc == 1) { + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_LINK_SUPERVISION_TIMEOUT; + rq.cparam = &cr->conn_info->handle; + rq.clen = 2; + rq.rparam = &rp; + rq.rlen = READ_LINK_SUPERVISION_TIMEOUT_RP_SIZE; + + if (hci_send_req(dd, &rq, 100) < 0) { + perror("HCI read_link_supervision_timeout request failed"); + exit(1); + } + + if (rp.status) { + fprintf(stderr, "HCI read_link_supervision_timeout failed (0x%2.2X)\n", + rp.status); + exit(1); + } + if (rp.link_sup_to) + printf("Link supervision timeout: %u slots (%.2f msec)\n", + rp.link_sup_to, (float)rp.link_sup_to * 0.625); + else + printf("Link supervision timeout never expires\n"); + } + else { + cp.handle = cr->conn_info->handle; + cp.link_sup_to = strtol(argv[1], NULL, 10); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_LINK_SUPERVISION_TIMEOUT; + rq.cparam = &cp; + rq.clen = WRITE_LINK_SUPERVISION_TIMEOUT_CP_SIZE; + + if (hci_send_req(dd, &rq, 100) < 0) { + perror("HCI write_link_supervision_timeout request failed"); + exit(1); + } + } + + close(dd); + free(cr); +} + struct { char *cmd; void (*func)(int dev_id, int argc, char **argv); @@ -967,6 +1078,7 @@ struct { { "cpt", cmd_cpt, "Change connection packet type" }, { "rssi", cmd_rssi, "Display connection RSSI" }, { "lq", cmd_link_quality, "Display link quality" }, + { "lst", cmd_link_sup_to, "Set/display link supervision timeout" }, { NULL, NULL, 0} }; -- cgit From d77d3f848c60d692cc9029ccf9a15b06f0704e90 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 20 Dec 2002 11:06:35 +0000 Subject: Make the info command reusing an existing connection handle --- tools/hcitool.c | 45 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 11 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index ec6f007a..dd289b04 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -386,7 +386,8 @@ static void cmd_info(int dev_id, int argc, char **argv) char name[248]; unsigned char features[8]; struct hci_version version; - int opt, dd; + struct hci_conn_info_req *cr; + int opt, dd, cc = 0; for_each_opt(opt, info_options, NULL) { switch(opt) { @@ -403,14 +404,19 @@ static void cmd_info(int dev_id, int argc, char **argv) return; } - baswap(&bdaddr, strtoba(argv[0])); + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); if (dev_id < 0) { dev_id = hci_get_route(&bdaddr); - if (dev_id < 0) { - fprintf(stderr, "Device is not available.\n"); - exit(1); - } + cc = 1; + } + + if (dev_id < 0) { + fprintf(stderr, "Device is not available or not connected.\n"); + exit(1); } printf("Requesting information ...\n"); @@ -421,13 +427,29 @@ static void cmd_info(int dev_id, int argc, char **argv) exit(1); } - printf("\tBD Address: %s\n", argv[0]); + if (cc) { + if (hci_create_connection(dd, &bdaddr, 0x0008 | 0x0010, 0, 0, &handle, 25000) < 0) { + perror("Can't create connection"); + close(dd); + exit(1); + } + } else { + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; - if (hci_create_connection(dd, &bdaddr, 0x0008 | 0x0010, 0, 0, &handle, 25000) < 0) { - close(dd); - exit(1); + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + handle = cr->conn_info->handle; } + printf("\tBD Address: %s\n", argv[0]); + if (hci_read_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0) printf("\tDevice Name: %s\n", name); @@ -444,7 +466,8 @@ static void cmd_info(int dev_id, int argc, char **argv) lmp_featurestostr(features, "\t\t", 3)); } - hci_disconnect(dd, handle, 0x13, 10000); + if (cc) + hci_disconnect(dd, handle, 0x13, 10000); close(dd); } -- cgit From 3e8471f6fc3e46a168ebb1bdfacdfb182c746f59 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 7 Jan 2003 17:52:56 +0000 Subject: Support for switch role command --- tools/hcitool.c | 215 +++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 149 insertions(+), 66 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index dd289b04..00c84b05 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -59,7 +59,7 @@ static int dev_info(int s, int dev_id, long arg) bdaddr_t bdaddr; if (ioctl(s, HCIGETDEVINFO, (void*) &di)) return 0; - + baswap(&bdaddr, &di.bdaddr); printf("\t%s\t%s\n", di.name, batostr(&bdaddr)); return 0; @@ -171,18 +171,18 @@ static void cmd_dev(int dev_id, int argc, char **argv) /* Inquiry */ static struct option inq_options[] = { - {"help", 0,0, 'h'}, - {"length", 1,0, 'l'}, - {"numrsp", 1,0, 'n'}, - {"flush", 0,0, 'f'}, + {"help", 0,0, 'h'}, + {"length", 1,0, 'l'}, + {"numrsp", 1,0, 'n'}, + {"flush", 0,0, 'f'}, {0, 0, 0, 0} }; static char *inq_help = "Usage:\n" "\tinq [--length=N] maximum inquiry duration in 1.28 s units\n" - "\t [--numrsp=N] specify maximum number of inquiry responses\n" - "\t [--flush] flush the inquiry cache\n"; + "\t [--numrsp=N] specify maximum number of inquiry responses\n" + "\t [--flush] flush the inquiry cache\n"; static void cmd_inq(int dev_id, int argc, char **argv) { @@ -200,7 +200,7 @@ static void cmd_inq(int dev_id, int argc, char **argv) case 'l': length = atoi(optarg); break; - + case 'n': num_rsp = atoi(optarg); break; @@ -236,10 +236,10 @@ static void cmd_inq(int dev_id, int argc, char **argv) /* Device scanning */ static struct option scan_options[] = { - {"help", 0,0, 'h'}, - {"length", 1,0, 'l'}, - {"numrsp", 1,0, 'n'}, - {"flush", 0,0, 'f'}, + {"help", 0,0, 'h'}, + {"length", 1,0, 'l'}, + {"numrsp", 1,0, 'n'}, + {"flush", 0,0, 'f'}, {0, 0, 0, 0} }; @@ -356,7 +356,7 @@ static void cmd_name(int dev_id, int argc, char **argv) } dd = hci_open_dev(dev_id); - if (dd < 0) { + if (dd < 0) { perror("HCI device open failed"); exit(1); } @@ -371,7 +371,7 @@ static void cmd_name(int dev_id, int argc, char **argv) /* Info about remote device */ static struct option info_options[] = { - {"help", 0,0, 'h'}, + {"help", 0,0, 'h'}, {0, 0, 0, 0} }; @@ -475,7 +475,7 @@ static void cmd_info(int dev_id, int argc, char **argv) /* Send arbitrary HCI commands */ static struct option cmd_options[] = { - {"help", 0,0, 'h'}, + {"help", 0,0, 'h'}, {0, 0, 0, 0} }; @@ -492,7 +492,7 @@ static void cmd_cmd(int dev_id, int argc, char **argv) hci_event_hdr *hdr; int i, opt, len, dd; uint16_t ocf; - uint8_t ogf; + uint8_t ogf; for_each_opt(opt, cmd_options, NULL) { switch(opt) { @@ -566,7 +566,7 @@ static void cmd_cmd(int dev_id, int argc, char **argv) /* Display active connections */ static struct option con_options[] = { - {"help", 0,0, 'h'}, + {"help", 0,0, 'h'}, {0, 0, 0, 0} }; @@ -593,9 +593,9 @@ static void cmd_con(int dev_id, int argc, char **argv) /* Create connection */ static struct option cc_options[] = { - {"help", 0,0, 'h'}, - {"role", 1,0, 'r'}, - {"ptype", 1,0, 'p'}, + {"help", 0,0, 'h'}, + {"role", 1,0, 'r'}, + {"ptype", 1,0, 'p'}, {0, 0, 0, 0} }; @@ -621,7 +621,7 @@ static void cmd_cc(int dev_id, int argc, char **argv) case 'p': hci_strtoptype(optarg, &ptype); break; - + case 'r': role = optarg[0] == 'm' ? 0 : 1; break; @@ -662,7 +662,7 @@ static void cmd_cc(int dev_id, int argc, char **argv) /* Close connection */ static struct option dc_options[] = { - {"help", 0,0, 'h'}, + {"help", 0,0, 'h'}, {0, 0, 0, 0} }; @@ -707,16 +707,16 @@ static void cmd_dc(int dev_id, int argc, char **argv) exit(1); } - cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; - bacpy(&cr->bdaddr, &bdaddr); - cr->type = ACL_LINK; - if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { perror("Get connection info failed"); - exit(1); - } + exit(1); + } hci_disconnect(dd, cr->conn_info->handle, 0x13, 100); @@ -724,10 +724,92 @@ static void cmd_dc(int dev_id, int argc, char **argv) free(cr); } +/* Role switch */ + +static struct option sr_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *sr_help = + "Usage:\n" + "\tsr \n"; + +static void cmd_sr(int dev_id, int argc, char **argv) +{ + struct hci_request rq; + switch_role_cp cp; + evt_role_change rp; + int opt, dd; + + for_each_opt(opt, sr_options, NULL) { + switch(opt) { + default: + printf(sr_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 2) { + printf(sr_help); + return; + } + + str2ba(argv[0], &cp.bdaddr); + switch (argv[1][0]) { + case 'm': + cp.role = 0; + break; + case 's': + cp.role = 1; + break; + default: + cp.role = atoi(argv[1]); + break; + } + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &cp.bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_POLICY; + rq.ocf = OCF_SWITCH_ROLE; + rq.cparam = &cp; + rq.clen = SWITCH_ROLE_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_ROLE_CHANGE_SIZE; + rq.event = EVT_ROLE_CHANGE; + + if (hci_send_req(dd, &rq, 300) < 0) { + perror("Switch role request failed"); + exit(1); + } + + if (rp.status) { + fprintf(stderr, "Switch role cmd failed (0x%2.2X)\n", rp.status); + exit(1); + } + + close(dd); +} + /* Read RSSI */ static struct option rssi_options[] = { - {"help", 0,0, 'h'}, + {"help", 0,0, 'h'}, {0, 0, 0, 0} }; @@ -738,7 +820,7 @@ static char *rssi_help = static void cmd_rssi(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; - struct hci_request rq; + struct hci_request rq; read_rssi_rp rp; bdaddr_t bdaddr; int opt, dd; @@ -776,7 +858,7 @@ static void cmd_rssi(int dev_id, int argc, char **argv) cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); if (!cr) - return; + return; bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -786,13 +868,13 @@ static void cmd_rssi(int dev_id, int argc, char **argv) } memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_STATUS_PARAM; - rq.ocf = OCF_READ_RSSI; + rq.ogf = OGF_STATUS_PARAM; + rq.ocf = OCF_READ_RSSI; rq.cparam = &cr->conn_info->handle; - rq.clen = 2; + rq.clen = 2; rq.rparam = &rp; - rq.rlen = READ_RSSI_RP_SIZE; - + rq.rlen = READ_RSSI_RP_SIZE; + if (hci_send_req(dd, &rq, 100) < 0) { perror("Read RSSI failed"); exit(1); @@ -803,7 +885,7 @@ static void cmd_rssi(int dev_id, int argc, char **argv) exit(1); } printf("\tRSSI return value: %d\n", rp.rssi); - + close(dd); free(cr); } @@ -811,7 +893,7 @@ static void cmd_rssi(int dev_id, int argc, char **argv) /* Get Link Quality */ static struct option link_quality_options[] = { - {"help", 0,0, 'h'}, + {"help", 0,0, 'h'}, {0, 0, 0, 0} }; @@ -822,7 +904,7 @@ static char *link_quality_help = static void cmd_link_quality(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; - struct hci_request rq; + struct hci_request rq; get_link_quality_rp rp; bdaddr_t bdaddr; int opt, dd; @@ -860,7 +942,7 @@ static void cmd_link_quality(int dev_id, int argc, char **argv) cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); if (!cr) - return; + return; bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -868,7 +950,7 @@ static void cmd_link_quality(int dev_id, int argc, char **argv) perror("Get connection info failed"); exit(1); } - + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_STATUS_PARAM; rq.ocf = OCF_GET_LINK_QUALITY; @@ -888,7 +970,7 @@ static void cmd_link_quality(int dev_id, int argc, char **argv) exit(1); } printf("Link quality: %d\n", rp.link_quality); - + close(dd); free(cr); } @@ -896,7 +978,7 @@ static void cmd_link_quality(int dev_id, int argc, char **argv) /* Set connection packet type */ static struct option cpt_options[] = { - {"help", 0,0, 'h'}, + {"help", 0,0, 'h'}, {0, 0, 0, 0} }; @@ -908,7 +990,7 @@ static void cmd_cpt(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; struct hci_request rq; - set_conn_ptype_cp cp; + set_conn_ptype_cp cp; evt_conn_ptype_changed rp; bdaddr_t bdaddr; int opt, dd, ptype; @@ -947,7 +1029,7 @@ static void cmd_cpt(int dev_id, int argc, char **argv) cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); if (!cr) - return; + return; bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -955,19 +1037,19 @@ static void cmd_cpt(int dev_id, int argc, char **argv) perror("Get connection info failed"); exit(1); } - + cp.handle = cr->conn_info->handle; cp.pkt_type = ptype; memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LINK_CTL; - rq.ocf = OCF_SET_CONN_PTYPE; + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_SET_CONN_PTYPE; rq.cparam = &cp; rq.clen = SET_CONN_PTYPE_CP_SIZE; rq.rparam = &rp; rq.rlen = EVT_CONN_PTYPE_CHANGED_SIZE; rq.event = EVT_CONN_PTYPE_CHANGED; - + if (hci_send_req(dd, &rq, 100) < 0) { perror("Packet type change failed"); exit(1); @@ -980,7 +1062,7 @@ static void cmd_cpt(int dev_id, int argc, char **argv) /* Get/Set Link Supervision Timeout */ static struct option link_supervision_options[] = { - {"help", 0,0, 'h'}, + {"help", 0,0, 'h'}, {0, 0, 0, 0} }; @@ -991,7 +1073,7 @@ static char *link_supervision_help = static void cmd_link_sup_to(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; - struct hci_request rq; + struct hci_request rq; read_link_supervision_timeout_rp rp; write_link_supervision_timeout_cp cp; bdaddr_t bdaddr; @@ -1030,7 +1112,7 @@ static void cmd_link_sup_to(int dev_id, int argc, char **argv) cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); if (!cr) - return; + return; bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1038,16 +1120,16 @@ static void cmd_link_sup_to(int dev_id, int argc, char **argv) perror("Get connection info failed"); exit(1); } - + if (argc == 1) { memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_READ_LINK_SUPERVISION_TIMEOUT; + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_LINK_SUPERVISION_TIMEOUT; rq.cparam = &cr->conn_info->handle; - rq.clen = 2; + rq.clen = 2; rq.rparam = &rp; - rq.rlen = READ_LINK_SUPERVISION_TIMEOUT_RP_SIZE; - + rq.rlen = READ_LINK_SUPERVISION_TIMEOUT_RP_SIZE; + if (hci_send_req(dd, &rq, 100) < 0) { perror("HCI read_link_supervision_timeout request failed"); exit(1); @@ -1069,11 +1151,11 @@ static void cmd_link_sup_to(int dev_id, int argc, char **argv) cp.link_sup_to = strtol(argv[1], NULL, 10); memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_WRITE_LINK_SUPERVISION_TIMEOUT; + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_LINK_SUPERVISION_TIMEOUT; rq.cparam = &cp; - rq.clen = WRITE_LINK_SUPERVISION_TIMEOUT_CP_SIZE; - + rq.clen = WRITE_LINK_SUPERVISION_TIMEOUT_CP_SIZE; + if (hci_send_req(dd, &rq, 100) < 0) { perror("HCI write_link_supervision_timeout request failed"); exit(1); @@ -1098,6 +1180,7 @@ struct { { "con", cmd_con, "Display active connections" }, { "cc", cmd_cc, "Create connection to remote device" }, { "dc", cmd_dc, "Disconnect from remote device" }, + { "sr", cmd_sr, "Switch master/slave role" }, { "cpt", cmd_cpt, "Change connection packet type" }, { "rssi", cmd_rssi, "Display connection RSSI" }, { "lq", cmd_link_quality, "Display link quality" }, @@ -1125,8 +1208,8 @@ static void usage(void) } static struct option main_options[] = { - {"help", 0,0, 'h'}, - {"device", 1,0, 'i'}, + {"help", 0,0, 'h'}, + {"device", 1,0, 'i'}, {0, 0, 0, 0} }; -- cgit From 723681ffa3035a55fe3a293add7e26da0e7296bd Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Tue, 8 Apr 2003 13:34:39 +0000 Subject: use constants; report errors --- tools/hcitool.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 00c84b05..f2ffb891 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -428,7 +428,7 @@ static void cmd_info(int dev_id, int argc, char **argv) } if (cc) { - if (hci_create_connection(dd, &bdaddr, 0x0008 | 0x0010, 0, 0, &handle, 25000) < 0) { + if (hci_create_connection(dd, &bdaddr, HCI_DM1 | HCI_DH1, 0, 0, &handle, 25000) < 0) { perror("Can't create connection"); close(dd); exit(1); @@ -467,7 +467,7 @@ static void cmd_info(int dev_id, int argc, char **argv) } if (cc) - hci_disconnect(dd, handle, 0x13, 10000); + hci_disconnect(dd, handle, HCI_OE_USER_ENDED_CONNECTION, 10000); close(dd); } @@ -655,7 +655,8 @@ static void cmd_cc(int dev_id, int argc, char **argv) exit(1); } - hci_create_connection(dd, &bdaddr, ptype, 0, role, &handle, 1000); + if (0 > hci_create_connection(dd, &bdaddr, ptype, 0, role, &handle, 1000)) + perror("Can't create connection"); hci_close_dev(dd); } @@ -718,7 +719,8 @@ static void cmd_dc(int dev_id, int argc, char **argv) exit(1); } - hci_disconnect(dd, cr->conn_info->handle, 0x13, 100); + if (0 > hci_disconnect(dd, cr->conn_info->handle, HCI_OE_USER_ENDED_CONNECTION, 100)) + perror("Disconnect failed"); close(dd); free(cr); -- cgit From 424f2b1bb5f34a89adc279c216bdf1f032dffa8d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 8 Apr 2003 14:51:17 +0000 Subject: Cleanup --- tools/hcitool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index f2ffb891..04d756eb 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -655,7 +655,7 @@ static void cmd_cc(int dev_id, int argc, char **argv) exit(1); } - if (0 > hci_create_connection(dd, &bdaddr, ptype, 0, role, &handle, 1000)) + if (hci_create_connection(dd, &bdaddr, ptype, 0, role, &handle, 1000) < 0) perror("Can't create connection"); hci_close_dev(dd); } @@ -719,7 +719,7 @@ static void cmd_dc(int dev_id, int argc, char **argv) exit(1); } - if (0 > hci_disconnect(dd, cr->conn_info->handle, HCI_OE_USER_ENDED_CONNECTION, 100)) + if (hci_disconnect(dd, cr->conn_info->handle, HCI_OE_USER_ENDED_CONNECTION, 100) < 0) perror("Disconnect failed"); close(dd); -- cgit From e7490562668965f3433aa4270b88ce55bfa9e1e3 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 18 Jun 2003 09:52:01 +0000 Subject: ... --- tools/hcitool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 04d756eb..a8f79f6d 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -282,7 +282,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) if (dev_id < 0) { dev_id = hci_get_route(&bdaddr); if (dev_id < 0) { - perror("Device is not available."); + perror("Device is not available"); exit(1); } } @@ -290,7 +290,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) printf("Scanning ...\n"); num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); if (num_rsp < 0) { - perror("Inquiry failed."); + perror("Inquiry failed"); exit(1); } -- cgit From 26d5498a00afec5ed676ef84ce1e7b94557ff46c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 26 Jun 2003 11:56:55 +0000 Subject: Add command for reading transmit power level --- tools/hcitool.c | 170 +++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 130 insertions(+), 40 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index a8f79f6d..88c53266 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -37,9 +37,9 @@ #include #include #include +#include #include #include -#include #include #include @@ -786,7 +786,7 @@ static void cmd_sr(int dev_id, int argc, char **argv) exit(1); } - memset(&rq, 0, sizeof(rq)); + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_POLICY; rq.ocf = OCF_SWITCH_ROLE; rq.cparam = &cp; @@ -869,7 +869,7 @@ static void cmd_rssi(int dev_id, int argc, char **argv) exit(1); } - memset(&rq, 0, sizeof(rq)); + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_STATUS_PARAM; rq.ocf = OCF_READ_RSSI; rq.cparam = &cr->conn_info->handle; @@ -886,24 +886,24 @@ static void cmd_rssi(int dev_id, int argc, char **argv) printf("Read RSSI returned (error) status 0x%2.2X\n", rp.status); exit(1); } - printf("\tRSSI return value: %d\n", rp.rssi); + printf("RSSI return value: %d\n", rp.rssi); close(dd); free(cr); } -/* Get Link Quality */ +/* Get link quality */ -static struct option link_quality_options[] = { +static struct option lq_options[] = { {"help", 0,0, 'h'}, {0, 0, 0, 0} }; -static char *link_quality_help = +static char *lq_help = "Usage:\n" "\tlq \n"; -static void cmd_link_quality(int dev_id, int argc, char **argv) +static void cmd_lq(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; struct hci_request rq; @@ -911,10 +911,10 @@ static void cmd_link_quality(int dev_id, int argc, char **argv) bdaddr_t bdaddr; int opt, dd; - for_each_opt(opt, link_quality_options, NULL) { + for_each_opt(opt, lq_options, NULL) { switch(opt) { default: - printf(link_quality_help); + printf(lq_help); return; } } @@ -922,7 +922,7 @@ static void cmd_link_quality(int dev_id, int argc, char **argv) argv += optind; if (argc < 1) { - printf(link_quality_help); + printf(lq_help); return; } @@ -953,13 +953,13 @@ static void cmd_link_quality(int dev_id, int argc, char **argv) exit(1); } - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_STATUS_PARAM; - rq.ocf = OCF_GET_LINK_QUALITY; + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_STATUS_PARAM; + rq.ocf = OCF_GET_LINK_QUALITY; rq.cparam = &cr->conn_info->handle; - rq.clen = 2; + rq.clen = 2; rq.rparam = &rp; - rq.rlen = GET_LINK_QUALITY_RP_SIZE; + rq.rlen = GET_LINK_QUALITY_RP_SIZE; if (hci_send_req(dd, &rq, 100) < 0) { perror("HCI get_link_quality request failed"); @@ -977,6 +977,95 @@ static void cmd_link_quality(int dev_id, int argc, char **argv) free(cr); } +/* Get transmit power level */ + +static struct option tpl_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *tpl_help = + "Usage:\n" + "\ttpl [type]\n"; + +static void cmd_tpl(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + struct hci_request rq; + read_transmit_power_level_cp cp; + read_transmit_power_level_rp rp; + bdaddr_t bdaddr; + int opt, dd; + + for_each_opt(opt, tpl_options, NULL) { + switch(opt) { + default: + printf(tpl_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(tpl_help); + return; + } + + str2ba(argv[0], &bdaddr); + cp.type = (argc > 1) ? atoi(argv[1]) : 0; + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + cp.handle = cr->conn_info->handle; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_TRANSMIT_POWER_LEVEL; + rq.cparam = &cp; + rq.clen = READ_TRANSMIT_POWER_LEVEL_CP_SIZE; + rq.rparam = &rp; + rq.rlen = READ_TRANSMIT_POWER_LEVEL_RP_SIZE; + + if (hci_send_req(dd, &rq, 100) < 0) { + perror("HCI read transmit power level request failed"); + exit(1); + } + + if (rp.status) { + fprintf(stderr, "HCI read_transmit_power_level cmd failed (0x%2.2X)\n", + rp.status); + exit(1); + } + printf("%s transmit power level: %d\n", + (cp.type == 0) ? "Current" : "Maximum", rp.level); + + close(dd); + free(cr); +} + /* Set connection packet type */ static struct option cpt_options[] = { @@ -1043,7 +1132,7 @@ static void cmd_cpt(int dev_id, int argc, char **argv) cp.handle = cr->conn_info->handle; cp.pkt_type = ptype; - memset(&rq, 0, sizeof(rq)); + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_SET_CONN_PTYPE; rq.cparam = &cp; @@ -1061,18 +1150,18 @@ static void cmd_cpt(int dev_id, int argc, char **argv) free(cr); } -/* Get/Set Link Supervision Timeout */ +/* Get/Set link supervision timeout */ -static struct option link_supervision_options[] = { +static struct option lst_options[] = { {"help", 0,0, 'h'}, {0, 0, 0, 0} }; -static char *link_supervision_help = +static char *lst_help = "Usage:\n" "\tlst [new value in slots]\n"; -static void cmd_link_sup_to(int dev_id, int argc, char **argv) +static void cmd_lst(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; struct hci_request rq; @@ -1081,10 +1170,10 @@ static void cmd_link_sup_to(int dev_id, int argc, char **argv) bdaddr_t bdaddr; int opt, dd; - for_each_opt(opt, link_supervision_options, NULL) { + for_each_opt(opt, lst_options, NULL) { switch(opt) { default: - printf(link_supervision_help); + printf(lst_help); return; } } @@ -1092,7 +1181,7 @@ static void cmd_link_sup_to(int dev_id, int argc, char **argv) argv += optind; if (argc < 1) { - printf(link_supervision_help); + printf(lst_help); return; } @@ -1124,7 +1213,7 @@ static void cmd_link_sup_to(int dev_id, int argc, char **argv) } if (argc == 1) { - memset(&rq, 0, sizeof(rq)); + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_READ_LINK_SUPERVISION_TIMEOUT; rq.cparam = &cr->conn_info->handle; @@ -1152,7 +1241,7 @@ static void cmd_link_sup_to(int dev_id, int argc, char **argv) cp.handle = cr->conn_info->handle; cp.link_sup_to = strtol(argv[1], NULL, 10); - memset(&rq, 0, sizeof(rq)); + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_WRITE_LINK_SUPERVISION_TIMEOUT; rq.cparam = &cp; @@ -1173,20 +1262,21 @@ struct { void (*func)(int dev_id, int argc, char **argv); char *doc; } command[] = { - { "dev", cmd_dev, "Display local devices" }, - { "inq", cmd_inq, "Inquire remote devices" }, - { "scan", cmd_scan, "Scan for remote devices" }, - { "name", cmd_name, "Get name from remote device" }, - { "info", cmd_info, "Get information from remote device" }, - { "cmd", cmd_cmd, "Submit arbitrary HCI commands" }, - { "con", cmd_con, "Display active connections" }, - { "cc", cmd_cc, "Create connection to remote device" }, - { "dc", cmd_dc, "Disconnect from remote device" }, - { "sr", cmd_sr, "Switch master/slave role" }, - { "cpt", cmd_cpt, "Change connection packet type" }, - { "rssi", cmd_rssi, "Display connection RSSI" }, - { "lq", cmd_link_quality, "Display link quality" }, - { "lst", cmd_link_sup_to, "Set/display link supervision timeout" }, + { "dev", cmd_dev, "Display local devices" }, + { "inq", cmd_inq, "Inquire remote devices" }, + { "scan", cmd_scan, "Scan for remote devices" }, + { "name", cmd_name, "Get name from remote device" }, + { "info", cmd_info, "Get information from remote device" }, + { "cmd", cmd_cmd, "Submit arbitrary HCI commands" }, + { "con", cmd_con, "Display active connections" }, + { "cc", cmd_cc, "Create connection to remote device" }, + { "dc", cmd_dc, "Disconnect from remote device" }, + { "sr", cmd_sr, "Switch master/slave role" }, + { "cpt", cmd_cpt, "Change connection packet type" }, + { "rssi", cmd_rssi, "Display connection RSSI" }, + { "lq", cmd_lq, "Display link quality" }, + { "tpl", cmd_tpl, "Display transmit power level" }, + { "lst", cmd_lst, "Set/display link supervision timeout" }, { NULL, NULL, 0} }; -- cgit From 6b410af5c3e83f36ed8b5a620f1ab3029a271058 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 24 Jul 2003 17:34:34 +0000 Subject: Kill usage of strtoba() and batostr() --- tools/hcitool.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 88c53266..59235270 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -56,12 +56,13 @@ static void usage(void); static int dev_info(int s, int dev_id, long arg) { struct hci_dev_info di = {dev_id: dev_id}; - bdaddr_t bdaddr; + char addr[18]; + if (ioctl(s, HCIGETDEVINFO, (void*) &di)) return 0; - baswap(&bdaddr, &di.bdaddr); - printf("\t%s\t%s\n", di.name, batostr(&bdaddr)); + ba2str(&di.bdaddr, addr); + printf("\t%s\t%s\n", di.name, addr); return 0; } @@ -89,12 +90,12 @@ static int conn_list(int s, int dev_id, long arg) } for (i=0; i < cl->conn_num; i++, ci++) { - bdaddr_t bdaddr; - baswap(&bdaddr, &ci->bdaddr); + char addr[18]; + ba2str(&ci->bdaddr, addr); printf("\t%s %s %s handle %d state %d lm %s\n", ci->out ? "<" : ">", ci->type == ACL_LINK ? "ACL" : "SCO", - batostr(&bdaddr), ci->handle, ci->state, + addr, ci->handle, ci->state, hci_lmtostr(ci->link_mode)); } return 0; @@ -188,7 +189,7 @@ static void cmd_inq(int dev_id, int argc, char **argv) { int num_rsp, length, flags; inquiry_info *info = NULL; - bdaddr_t bdaddr; + char addr[18]; int i, opt; length = 8; /* ~10 seconds */ @@ -223,9 +224,9 @@ static void cmd_inq(int dev_id, int argc, char **argv) } for (i = 0; i < num_rsp; i++) { - baswap(&bdaddr, &(info+i)->bdaddr); + ba2str(&(info+i)->bdaddr, addr); printf("\t%s\tclock offset: 0x%4.4x\tclass: 0x%2.2x%2.2x%2.2x\n", - batostr(&bdaddr), (info+i)->clock_offset, + addr, (info+i)->clock_offset, (info+i)->dev_class[2], (info+i)->dev_class[1], (info+i)->dev_class[0]); @@ -251,7 +252,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) { inquiry_info *info = NULL; int num_rsp, length, flags; - bdaddr_t bdaddr; + char addr[18]; char name[248]; int i, opt, dd; @@ -280,7 +281,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) } if (dev_id < 0) { - dev_id = hci_get_route(&bdaddr); + dev_id = hci_get_route(NULL); if (dev_id < 0) { perror("Device is not available"); exit(1); @@ -305,8 +306,8 @@ static void cmd_scan(int dev_id, int argc, char **argv) memset(name, 0, sizeof(name)); if (hci_read_remote_name(dd, &(info+i)->bdaddr, sizeof(name), name, 100000) < 0) strcpy(name, "n/a"); - baswap(&bdaddr, &(info+i)->bdaddr); - printf("\t%s\t%s\n", batostr(&bdaddr), name); + ba2str(&(info+i)->bdaddr, addr); + printf("\t%s\t%s\n", addr, name); } close(dd); @@ -345,7 +346,7 @@ static void cmd_name(int dev_id, int argc, char **argv) return; } - baswap(&bdaddr, strtoba(argv[0])); + str2ba(argv[0], &bdaddr); if (dev_id < 0) { dev_id = hci_get_route(&bdaddr); -- cgit From 7fbea8e4421d04d23747ad4dbcc31aa2d10e0c74 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 18 Nov 2003 11:38:31 +0000 Subject: Display all 8 bytes of the features --- tools/hcitool.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 59235270..cd546735 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -462,8 +462,9 @@ static void cmd_info(int dev_id, int argc, char **argv) } if (hci_read_remote_features(dd, handle, features, 20000) == 0) { - printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n%s\n", + printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n%s\n", features[0], features[1], features[2], features[3], + features[4], features[5], features[6], features[7], lmp_featurestostr(features, "\t\t", 3)); } -- cgit From 8793e6002250dde7f85ab89410ad96aebf2dbb76 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 16 Dec 2003 18:45:07 +0000 Subject: Increase number of inquiry responses --- tools/hcitool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index cd546735..f8125f43 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -193,7 +193,7 @@ static void cmd_inq(int dev_id, int argc, char **argv) int i, opt; length = 8; /* ~10 seconds */ - num_rsp = 10; + num_rsp = 100; flags = 0; for_each_opt(opt, inq_options, NULL) { @@ -257,7 +257,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) int i, opt, dd; length = 8; /* ~10 seconds */ - num_rsp = 10; + num_rsp = 100; flags = 0; for_each_opt(opt, scan_options, NULL) { -- cgit From 16e217b4b13b828a9bb6c372d544deafa0e01f24 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 21 Dec 2003 16:08:25 +0000 Subject: Fix automatic connection creation for the info command --- tools/hcitool.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index f8125f43..0194b650 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -410,10 +410,8 @@ static void cmd_info(int dev_id, int argc, char **argv) if (dev_id < 0) dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); - if (dev_id < 0) { + if (dev_id < 0) dev_id = hci_get_route(&bdaddr); - cc = 1; - } if (dev_id < 0) { fprintf(stderr, "Device is not available or not connected.\n"); @@ -428,26 +426,24 @@ static void cmd_info(int dev_id, int argc, char **argv) exit(1); } - if (cc) { + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) { + perror("Can't get connection info"); + close(dd); + exit(1); + } + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { if (hci_create_connection(dd, &bdaddr, HCI_DM1 | HCI_DH1, 0, 0, &handle, 25000) < 0) { perror("Can't create connection"); close(dd); exit(1); } - } else { - cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; - - bacpy(&cr->bdaddr, &bdaddr); - cr->type = ACL_LINK; - if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { - perror("Get connection info failed"); - exit(1); - } - + cc = 1; + } else handle = cr->conn_info->handle; - } printf("\tBD Address: %s\n", argv[0]); -- cgit From 2cabb56f7528c9756617dbae8a73d9878bfa9b59 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 15 Feb 2004 23:25:53 +0000 Subject: Fix endian problem with hci_create_connection() --- tools/hcitool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 0194b650..675d829e 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -436,7 +436,7 @@ static void cmd_info(int dev_id, int argc, char **argv) bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { - if (hci_create_connection(dd, &bdaddr, HCI_DM1 | HCI_DH1, 0, 0, &handle, 25000) < 0) { + if (hci_create_connection(dd, &bdaddr, htobs(HCI_DM1 | HCI_DH1), 0, 0, &handle, 25000) < 0) { perror("Can't create connection"); close(dd); exit(1); @@ -653,7 +653,7 @@ static void cmd_cc(int dev_id, int argc, char **argv) exit(1); } - if (hci_create_connection(dd, &bdaddr, ptype, 0, role, &handle, 1000) < 0) + if (hci_create_connection(dd, &bdaddr, htobs(ptype), 0, role, &handle, 1000) < 0) perror("Can't create connection"); hci_close_dev(dd); } -- cgit From f3be9c15792728861db02c8b0a3692903a30552b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 18 Feb 2004 23:20:50 +0000 Subject: Add command for authentication request --- tools/hcitool.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 85 insertions(+), 2 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 675d829e..3a4a59ef 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1255,6 +1255,88 @@ static void cmd_lst(int dev_id, int argc, char **argv) free(cr); } +/* Request authentication */ + +static struct option auth_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *auth_help = + "Usage:\n" + "\tauth \n"; + +static void cmd_auth(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + struct hci_request rq; + auth_requested_cp cp; + evt_auth_complete rp; + bdaddr_t bdaddr; + int opt, dd; + + for_each_opt(opt, auth_options, NULL) { + switch(opt) { + default: + printf(auth_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(auth_help); + return; + } + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + cp.handle = cr->conn_info->handle; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_AUTH_REQUESTED; + rq.cparam = &cp; + rq.clen = AUTH_REQUESTED_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_AUTH_COMPLETE_SIZE; + rq.event = EVT_AUTH_COMPLETE; + + if (hci_send_req(dd, &rq, 25000) < 0) { + perror("HCI authentication request failed"); + exit(1); + } + + close(dd); + free(cr); +} + struct { char *cmd; void (*func)(int dev_id, int argc, char **argv); @@ -1268,14 +1350,15 @@ struct { { "cmd", cmd_cmd, "Submit arbitrary HCI commands" }, { "con", cmd_con, "Display active connections" }, { "cc", cmd_cc, "Create connection to remote device" }, - { "dc", cmd_dc, "Disconnect from remote device" }, + { "dc", cmd_dc, "Disconnect from remote device" }, { "sr", cmd_sr, "Switch master/slave role" }, { "cpt", cmd_cpt, "Change connection packet type" }, { "rssi", cmd_rssi, "Display connection RSSI" }, { "lq", cmd_lq, "Display link quality" }, { "tpl", cmd_tpl, "Display transmit power level" }, { "lst", cmd_lst, "Set/display link supervision timeout" }, - { NULL, NULL, 0} + { "auth", cmd_auth, "Request authentication" }, + { NULL, NULL, 0 } }; static void usage(void) -- cgit From 4352b6d63fb5eb038e5f678ae143f97662b7db3b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 21 Mar 2004 21:25:22 +0000 Subject: Add support for setting connection encryption --- tools/hcitool.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 98 insertions(+), 15 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 3a4a59ef..8fd7b83d 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -146,7 +146,7 @@ static void hex_dump(char *pref, int width, unsigned char *buf, int len) /* Display local devices */ static struct option dev_options[] = { - {"help", 0,0, 'h'}, + {"help", 0,0, 'h'}, {0, 0, 0, 0} }; @@ -265,7 +265,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) case 'l': length = atoi(optarg); break; - + case 'n': num_rsp = atoi(optarg); break; @@ -317,7 +317,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) /* Remote name */ static struct option name_options[] = { - {"help", 0,0, 'h'}, + {"help", 0,0, 'h'}, {0, 0, 0, 0} }; @@ -699,7 +699,7 @@ static void cmd_dc(int dev_id, int argc, char **argv) exit(1); } } - + dd = hci_open_dev(dev_id); if (dd < 0) { perror("HCI device open failed"); @@ -849,7 +849,7 @@ static void cmd_rssi(int dev_id, int argc, char **argv) exit(1); } } - + dd = hci_open_dev(dev_id); if (dd < 0) { perror("HCI device open failed"); @@ -866,7 +866,7 @@ static void cmd_rssi(int dev_id, int argc, char **argv) perror("Get connection info failed"); exit(1); } - + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_STATUS_PARAM; rq.ocf = OCF_READ_RSSI; @@ -933,7 +933,7 @@ static void cmd_lq(int dev_id, int argc, char **argv) exit(1); } } - + dd = hci_open_dev(dev_id); if (dd < 0) { perror("HCI device open failed"); @@ -958,7 +958,7 @@ static void cmd_lq(int dev_id, int argc, char **argv) rq.clen = 2; rq.rparam = &rp; rq.rlen = GET_LINK_QUALITY_RP_SIZE; - + if (hci_send_req(dd, &rq, 100) < 0) { perror("HCI get_link_quality request failed"); exit(1); @@ -1020,7 +1020,7 @@ static void cmd_tpl(int dev_id, int argc, char **argv) exit(1); } } - + dd = hci_open_dev(dev_id); if (dd < 0) { perror("HCI device open failed"); @@ -1046,7 +1046,7 @@ static void cmd_tpl(int dev_id, int argc, char **argv) rq.clen = READ_TRANSMIT_POWER_LEVEL_CP_SIZE; rq.rparam = &rp; rq.rlen = READ_TRANSMIT_POWER_LEVEL_RP_SIZE; - + if (hci_send_req(dd, &rq, 100) < 0) { perror("HCI read transmit power level request failed"); exit(1); @@ -1109,7 +1109,7 @@ static void cmd_cpt(int dev_id, int argc, char **argv) exit(1); } } - + dd = hci_open_dev(dev_id); if (dd < 0) { perror("HCI device open failed"); @@ -1192,7 +1192,7 @@ static void cmd_lst(int dev_id, int argc, char **argv) exit(1); } } - + dd = hci_open_dev(dev_id); if (dd < 0) { perror("HCI device open failed"); @@ -1234,8 +1234,7 @@ static void cmd_lst(int dev_id, int argc, char **argv) rp.link_sup_to, (float)rp.link_sup_to * 0.625); else printf("Link supervision timeout never expires\n"); - } - else { + } else { cp.handle = cr->conn_info->handle; cp.link_sup_to = strtol(argv[1], NULL, 10); @@ -1337,7 +1336,90 @@ static void cmd_auth(int dev_id, int argc, char **argv) free(cr); } -struct { +/* Activate encryption */ + +static struct option enc_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *enc_help = + "Usage:\n" + "\tenc [encrypt enable]\n"; + +static void cmd_enc(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + struct hci_request rq; + set_conn_encrypt_cp cp; + evt_encrypt_change rp; + bdaddr_t bdaddr; + int opt, dd; + + for_each_opt(opt, enc_options, NULL) { + switch(opt) { + default: + printf(enc_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(enc_help); + return; + } + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + cp.handle = cr->conn_info->handle; + cp.encrypt = (argc > 1) ? atoi(argv[1]) : 1; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_SET_CONN_ENCRYPT; + rq.cparam = &cp; + rq.clen = SET_CONN_ENCRYPT_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_ENCRYPT_CHANGE_SIZE; + rq.event = EVT_ENCRYPT_CHANGE; + + if (hci_send_req(dd, &rq, 25000) < 0) { + perror("HCI set encryption request failed"); + exit(1); + } + + close(dd); + free(cr); +} + +static struct { char *cmd; void (*func)(int dev_id, int argc, char **argv); char *doc; @@ -1358,6 +1440,7 @@ struct { { "tpl", cmd_tpl, "Display transmit power level" }, { "lst", cmd_lst, "Set/display link supervision timeout" }, { "auth", cmd_auth, "Request authentication" }, + { "enc", cmd_enc, "Set connection encryption" }, { NULL, NULL, 0 } }; -- cgit From 1d3715db11f573060cb02a2b7b7c44f06607d337 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 3 Apr 2004 06:04:35 +0000 Subject: Update BlueZ library configuration --- tools/hcitool.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 8fd7b83d..667212fe 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -25,6 +25,10 @@ * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include -- cgit From 44d98edef4ab08644f87ebfb67ab6d5fb41ffa14 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 19 Apr 2004 13:12:13 +0000 Subject: Fix more endian bugs for the ACL handle --- tools/hcitool.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 667212fe..37450098 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -447,7 +447,7 @@ static void cmd_info(int dev_id, int argc, char **argv) } cc = 1; } else - handle = cr->conn_info->handle; + handle = htobs(cr->conn_info->handle); printf("\tBD Address: %s\n", argv[0]); @@ -721,7 +721,7 @@ static void cmd_dc(int dev_id, int argc, char **argv) exit(1); } - if (hci_disconnect(dd, cr->conn_info->handle, HCI_OE_USER_ENDED_CONNECTION, 100) < 0) + if (hci_disconnect(dd, htobs(cr->conn_info->handle), HCI_OE_USER_ENDED_CONNECTION, 100) < 0) perror("Disconnect failed"); close(dd); @@ -827,6 +827,7 @@ static void cmd_rssi(int dev_id, int argc, char **argv) struct hci_request rq; read_rssi_rp rp; bdaddr_t bdaddr; + uint16_t handle; int opt, dd; for_each_opt(opt, rssi_options, NULL) { @@ -871,10 +872,12 @@ static void cmd_rssi(int dev_id, int argc, char **argv) exit(1); } + handle = htobs(cr->conn_info->handle); + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_STATUS_PARAM; rq.ocf = OCF_READ_RSSI; - rq.cparam = &cr->conn_info->handle; + rq.cparam = &handle; rq.clen = 2; rq.rparam = &rp; rq.rlen = READ_RSSI_RP_SIZE; @@ -911,6 +914,7 @@ static void cmd_lq(int dev_id, int argc, char **argv) struct hci_request rq; get_link_quality_rp rp; bdaddr_t bdaddr; + uint16_t handle; int opt, dd; for_each_opt(opt, lq_options, NULL) { @@ -955,10 +959,12 @@ static void cmd_lq(int dev_id, int argc, char **argv) exit(1); } + handle = htobs(cr->conn_info->handle); + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_STATUS_PARAM; rq.ocf = OCF_GET_LINK_QUALITY; - rq.cparam = &cr->conn_info->handle; + rq.cparam = &handle; rq.clen = 2; rq.rparam = &rp; rq.rlen = GET_LINK_QUALITY_RP_SIZE; @@ -1041,7 +1047,7 @@ static void cmd_tpl(int dev_id, int argc, char **argv) perror("Get connection info failed"); exit(1); } - cp.handle = cr->conn_info->handle; + cp.handle = htobs(cr->conn_info->handle); memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; @@ -1131,7 +1137,7 @@ static void cmd_cpt(int dev_id, int argc, char **argv) exit(1); } - cp.handle = cr->conn_info->handle; + cp.handle = htobs(cr->conn_info->handle); cp.pkt_type = ptype; memset(&rq, 0, sizeof(rq)); @@ -1170,6 +1176,7 @@ static void cmd_lst(int dev_id, int argc, char **argv) read_link_supervision_timeout_rp rp; write_link_supervision_timeout_cp cp; bdaddr_t bdaddr; + uint16_t handle; int opt, dd; for_each_opt(opt, lst_options, NULL) { @@ -1214,11 +1221,13 @@ static void cmd_lst(int dev_id, int argc, char **argv) exit(1); } + handle = htobs(cr->conn_info->handle); + if (argc == 1) { memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_READ_LINK_SUPERVISION_TIMEOUT; - rq.cparam = &cr->conn_info->handle; + rq.cparam = &handle; rq.clen = 2; rq.rparam = &rp; rq.rlen = READ_LINK_SUPERVISION_TIMEOUT_RP_SIZE; @@ -1239,7 +1248,7 @@ static void cmd_lst(int dev_id, int argc, char **argv) else printf("Link supervision timeout never expires\n"); } else { - cp.handle = cr->conn_info->handle; + cp.handle = htobs(cr->conn_info->handle); cp.link_sup_to = strtol(argv[1], NULL, 10); memset(&rq, 0, sizeof(rq)); @@ -1320,7 +1329,7 @@ static void cmd_auth(int dev_id, int argc, char **argv) exit(1); } - cp.handle = cr->conn_info->handle; + cp.handle = htobs(cr->conn_info->handle); memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; @@ -1402,7 +1411,7 @@ static void cmd_enc(int dev_id, int argc, char **argv) exit(1); } - cp.handle = cr->conn_info->handle; + cp.handle = htobs(cr->conn_info->handle); cp.encrypt = (argc > 1) ? atoi(argv[1]) : 1; memset(&rq, 0, sizeof(rq)); -- cgit From 7b44fb1986b0bae4fc37130c22a975972261f851 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 25 Apr 2004 14:12:26 +0000 Subject: The lmp_featurestostr() now uses a character number as width --- tools/hcitool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 37450098..b01f78d6 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -465,7 +465,7 @@ static void cmd_info(int dev_id, int argc, char **argv) printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n%s\n", features[0], features[1], features[2], features[3], features[4], features[5], features[6], features[7], - lmp_featurestostr(features, "\t\t", 3)); + lmp_featurestostr(features, "\t\t", 63)); } if (cc) -- cgit From 56cbbde9aaecbfdd1f1e4c820de92110355aa365 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 25 Apr 2004 19:11:20 +0000 Subject: Add support for getting the AFH channel map --- tools/hcitool.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index b01f78d6..99355861 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1074,6 +1074,102 @@ static void cmd_tpl(int dev_id, int argc, char **argv) free(cr); } +/* Get AFH channel map */ + +static struct option afh_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *afh_help = + "Usage:\n" + "\tafh \n"; + +static void cmd_afh(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + struct hci_request rq; + read_afh_map_rp rp; + bdaddr_t bdaddr; + uint16_t handle; + int opt, dd; + + for_each_opt(opt, afh_options, NULL) { + switch(opt) { + default: + printf(afh_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(afh_help); + return; + } + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + handle = htobs(cr->conn_info->handle); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_STATUS_PARAM; + rq.ocf = OCF_READ_AFH_MAP; + rq.cparam = &handle; + rq.clen = 2; + rq.rparam = &rp; + rq.rlen = READ_AFH_MAP_RP_SIZE; + + if (hci_send_req(dd, &rq, 100) < 0) { + perror("HCI read AFH map request failed"); + exit(1); + } + + if (rp.status) { + fprintf(stderr, "HCI read_afh_map cmd failed (0x%2.2X)\n", + rp.status); + exit(1); + } + + if (rp.mode == 0x01) { + int i; + printf("AFH map: 0x"); + for (i = 0; i < 10; i++) + printf("%02x", rp.map[i]); + printf("\n"); + } else + printf("AFH disabled\n"); + + close(dd); + free(cr); +} + /* Set connection packet type */ static struct option cpt_options[] = { @@ -1451,6 +1547,7 @@ static struct { { "rssi", cmd_rssi, "Display connection RSSI" }, { "lq", cmd_lq, "Display link quality" }, { "tpl", cmd_tpl, "Display transmit power level" }, + { "afh", cmd_afh, "Display AFH channel map" }, { "lst", cmd_lst, "Set/display link supervision timeout" }, { "auth", cmd_auth, "Request authentication" }, { "enc", cmd_enc, "Set connection encryption" }, -- cgit From b66d3f9b2cb8934a0eb7ac07f347001984488ac6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 28 Apr 2004 10:39:47 +0000 Subject: Unify copyright and license information --- tools/hcitool.c | 51 +++++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 24 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 99355861..5cecdf7e 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1,28 +1,31 @@ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ - /* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ #ifdef HAVE_CONFIG_H -- cgit From f3ba72e2b071ba40bfe535a4b76193100a956462 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 12 Jun 2004 09:41:17 +0000 Subject: Change timeout for create connection --- tools/hcitool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 5cecdf7e..8f03ae86 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -660,7 +660,7 @@ static void cmd_cc(int dev_id, int argc, char **argv) exit(1); } - if (hci_create_connection(dd, &bdaddr, htobs(ptype), 0, role, &handle, 1000) < 0) + if (hci_create_connection(dd, &bdaddr, htobs(ptype), 0, role, &handle, 25000) < 0) perror("Can't create connection"); hci_close_dev(dd); } -- cgit From 01e800f18ea32d2b9d285bb245d303e3aa81fc3b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 25 Jul 2004 07:36:18 +0000 Subject: Use packet type and allow role switch --- tools/hcitool.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 8f03ae86..df33412f 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -394,6 +394,7 @@ static void cmd_info(int dev_id, int argc, char **argv) char name[248]; unsigned char features[8]; struct hci_version version; + struct hci_dev_info di; struct hci_conn_info_req *cr; int opt, dd, cc = 0; @@ -425,6 +426,11 @@ static void cmd_info(int dev_id, int argc, char **argv) exit(1); } + if (hci_devinfo(dev_id, &di) < 0) { + perror("Can't get device info"); + exit(1); + } + printf("Requesting information ...\n"); dd = hci_open_dev(dev_id); @@ -443,7 +449,7 @@ static void cmd_info(int dev_id, int argc, char **argv) bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { - if (hci_create_connection(dd, &bdaddr, htobs(HCI_DM1 | HCI_DH1), 0, 0, &handle, 25000) < 0) { + if (hci_create_connection(dd, &bdaddr, htobs(di.pkt_type & ACL_PTYPE_MASK), 0, 0x01, &handle, 25000) < 0) { perror("Can't create connection"); close(dd); exit(1); @@ -618,7 +624,7 @@ static void cmd_cc(int dev_id, int argc, char **argv) uint16_t handle; uint8_t role; - role = 0; + role = 0x01; ptype = HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5; for_each_opt(opt, cc_options, NULL) { -- cgit From b3f9653837d74d6866c90114e52d9d4c024d6423 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 20 Oct 2004 05:51:25 +0000 Subject: Wait some time before calling disconnect --- tools/hcitool.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index df33412f..089ca103 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -477,8 +477,10 @@ static void cmd_info(int dev_id, int argc, char **argv) lmp_featurestostr(features, "\t\t", 63)); } - if (cc) + if (cc) { + usleep(10000); hci_disconnect(dd, handle, HCI_OE_USER_ENDED_CONNECTION, 10000); + } close(dd); } -- cgit From 7e08a09c87660616b173f338aff9baf3f7b61f5d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 25 Oct 2004 07:20:17 +0000 Subject: Use Bluetooth library functions --- tools/hcitool.c | 67 +++++++++++---------------------------------------------- 1 file changed, 13 insertions(+), 54 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 089ca103..7cb807ec 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -732,7 +732,7 @@ static void cmd_dc(int dev_id, int argc, char **argv) exit(1); } - if (hci_disconnect(dd, htobs(cr->conn_info->handle), HCI_OE_USER_ENDED_CONNECTION, 100) < 0) + if (hci_disconnect(dd, htobs(cr->conn_info->handle), HCI_OE_USER_ENDED_CONNECTION, 10000) < 0) perror("Disconnect failed"); close(dd); @@ -752,9 +752,8 @@ static char *sr_help = static void cmd_sr(int dev_id, int argc, char **argv) { - struct hci_request rq; - switch_role_cp cp; - evt_role_change rp; + bdaddr_t bdaddr; + uint8_t role; int opt, dd; for_each_opt(opt, sr_options, NULL) { @@ -772,21 +771,21 @@ static void cmd_sr(int dev_id, int argc, char **argv) return; } - str2ba(argv[0], &cp.bdaddr); + str2ba(argv[0], &bdaddr); switch (argv[1][0]) { case 'm': - cp.role = 0; + role = 0; break; case 's': - cp.role = 1; + role = 1; break; default: - cp.role = atoi(argv[1]); + role = atoi(argv[1]); break; } if (dev_id < 0) { - dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &cp.bdaddr); + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); if (dev_id < 0) { fprintf(stderr, "Not connected.\n"); exit(1); @@ -799,25 +798,11 @@ static void cmd_sr(int dev_id, int argc, char **argv) exit(1); } - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LINK_POLICY; - rq.ocf = OCF_SWITCH_ROLE; - rq.cparam = &cp; - rq.clen = SWITCH_ROLE_CP_SIZE; - rq.rparam = &rp; - rq.rlen = EVT_ROLE_CHANGE_SIZE; - rq.event = EVT_ROLE_CHANGE; - - if (hci_send_req(dd, &rq, 300) < 0) { + if (hci_switch_role(dd, &bdaddr, role, 10000) < 0) { perror("Switch role request failed"); exit(1); } - if (rp.status) { - fprintf(stderr, "Switch role cmd failed (0x%2.2X)\n", rp.status); - exit(1); - } - close(dd); } @@ -1388,9 +1373,6 @@ static char *auth_help = static void cmd_auth(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; - struct hci_request rq; - auth_requested_cp cp; - evt_auth_complete rp; bdaddr_t bdaddr; int opt, dd; @@ -1436,18 +1418,7 @@ static void cmd_auth(int dev_id, int argc, char **argv) exit(1); } - cp.handle = htobs(cr->conn_info->handle); - - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LINK_CTL; - rq.ocf = OCF_AUTH_REQUESTED; - rq.cparam = &cp; - rq.clen = AUTH_REQUESTED_CP_SIZE; - rq.rparam = &rp; - rq.rlen = EVT_AUTH_COMPLETE_SIZE; - rq.event = EVT_AUTH_COMPLETE; - - if (hci_send_req(dd, &rq, 25000) < 0) { + if (hci_authenticate_link(dd, htobs(cr->conn_info->handle), 25000) < 0) { perror("HCI authentication request failed"); exit(1); } @@ -1470,10 +1441,8 @@ static char *enc_help = static void cmd_enc(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; - struct hci_request rq; - set_conn_encrypt_cp cp; - evt_encrypt_change rp; bdaddr_t bdaddr; + uint8_t encrypt; int opt, dd; for_each_opt(opt, enc_options, NULL) { @@ -1518,19 +1487,9 @@ static void cmd_enc(int dev_id, int argc, char **argv) exit(1); } - cp.handle = htobs(cr->conn_info->handle); - cp.encrypt = (argc > 1) ? atoi(argv[1]) : 1; - - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LINK_CTL; - rq.ocf = OCF_SET_CONN_ENCRYPT; - rq.cparam = &cp; - rq.clen = SET_CONN_ENCRYPT_CP_SIZE; - rq.rparam = &rp; - rq.rlen = EVT_ENCRYPT_CHANGE_SIZE; - rq.event = EVT_ENCRYPT_CHANGE; + encrypt = (argc > 1) ? atoi(argv[1]) : 1; - if (hci_send_req(dd, &rq, 25000) < 0) { + if (hci_encrypt_link(dd, htobs(cr->conn_info->handle), encrypt, 25000) < 0) { perror("HCI set encryption request failed"); exit(1); } -- cgit From 1c111444bad2e4f0d66874a9032e43f91cb6cc3f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 4 Nov 2004 11:18:50 +0000 Subject: Some whitespace cleanup --- tools/hcitool.c | 102 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 55 insertions(+), 47 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 7cb807ec..6c41483b 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -65,7 +65,7 @@ static int dev_info(int s, int dev_id, long arg) struct hci_dev_info di = {dev_id: dev_id}; char addr[18]; - if (ioctl(s, HCIGETDEVINFO, (void*) &di)) + if (ioctl(s, HCIGETDEVINFO, (void *) &di)) return 0; ba2str(&di.bdaddr, addr); @@ -91,12 +91,12 @@ static int conn_list(int s, int dev_id, long arg) cl->conn_num = 10; ci = cl->conn_info; - if (ioctl(s, HCIGETCONNLIST, (void*)cl)) { + if (ioctl(s, HCIGETCONNLIST, (void *) cl)) { perror("Can't get connection list"); exit(1); } - for (i=0; i < cl->conn_num; i++, ci++) { + for (i = 0; i < cl->conn_num; i++, ci++) { char addr[18]; ba2str(&ci->bdaddr, addr); printf("\t%s %s %s handle %d state %d lm %s\n", @@ -105,6 +105,7 @@ static int conn_list(int s, int dev_id, long arg) addr, ci->handle, ci->state, hci_lmtostr(ci->link_mode)); } + return 0; } @@ -122,14 +123,15 @@ static int find_conn(int s, int dev_id, long arg) cl->conn_num = 10; ci = cl->conn_info; - if (ioctl(s, HCIGETCONNLIST, (void*)cl)) { + if (ioctl(s, HCIGETCONNLIST, (void *) cl)) { perror("Can't get connection list"); exit(1); } - for (i=0; i < cl->conn_num; i++, ci++) - if (!bacmp((bdaddr_t *)arg, &ci->bdaddr)) + for (i = 0; i < cl->conn_num; i++, ci++) + if (!bacmp((bdaddr_t *) arg, &ci->bdaddr)) return 1; + return 0; } @@ -137,7 +139,7 @@ static void hex_dump(char *pref, int width, unsigned char *buf, int len) { register int i,n; - for (i=0, n=1; ibdaddr, &bdaddr); cr->type = ACL_LINK; if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { - if (hci_create_connection(dd, &bdaddr, htobs(di.pkt_type & ACL_PTYPE_MASK), 0, 0x01, &handle, 25000) < 0) { + if (hci_create_connection(dd, &bdaddr, + htobs(di.pkt_type & ACL_PTYPE_MASK), + 0, 0x01, &handle, 25000) < 0) { perror("Can't create connection"); close(dd); exit(1); @@ -466,15 +469,18 @@ static void cmd_info(int dev_id, int argc, char **argv) if (hci_read_remote_version(dd, handle, &version, 20000) == 0) { printf("\tLMP Version: %s (0x%x) LMP Subversion: 0x%x\n" "\tManufacturer: %s (%d)\n", - lmp_vertostr(version.lmp_ver), version.lmp_ver, version.lmp_subver, - bt_compidtostr(version.manufacturer), version.manufacturer); + lmp_vertostr(version.lmp_ver), + version.lmp_ver, + version.lmp_subver, + bt_compidtostr(version.manufacturer), + version.manufacturer); } if (hci_read_remote_features(dd, handle, features, 20000) == 0) { printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n%s\n", - features[0], features[1], features[2], features[3], - features[4], features[5], features[6], features[7], - lmp_featurestostr(features, "\t\t", 63)); + features[0], features[1], features[2], features[3], + features[4], features[5], features[6], features[7], + lmp_featurestostr(features, "\t\t", 63)); } if (cc) { @@ -508,7 +514,7 @@ static void cmd_cmd(int dev_id, int argc, char **argv) uint8_t ogf; for_each_opt(opt, cmd_options, NULL) { - switch(opt) { + switch (opt) { default: printf(cmd_help); return; @@ -573,7 +579,6 @@ static void cmd_cmd(int dev_id, int argc, char **argv) hex_dump(" ", 20, ptr, len); fflush(stdout); hci_close_dev(dd); - return; } /* Display active connections */ @@ -592,7 +597,7 @@ static void cmd_con(int dev_id, int argc, char **argv) int opt; for_each_opt(opt, con_options, NULL) { - switch(opt) { + switch (opt) { default: printf(con_help); return; @@ -630,7 +635,7 @@ static void cmd_cc(int dev_id, int argc, char **argv) ptype = HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5; for_each_opt(opt, cc_options, NULL) { - switch(opt) { + switch (opt) { case 'p': hci_strtoptype(optarg, &ptype); break; @@ -668,7 +673,8 @@ static void cmd_cc(int dev_id, int argc, char **argv) exit(1); } - if (hci_create_connection(dd, &bdaddr, htobs(ptype), 0, role, &handle, 25000) < 0) + if (hci_create_connection(dd, &bdaddr, htobs(ptype), + 0, role, &handle, 25000) < 0) perror("Can't create connection"); hci_close_dev(dd); } @@ -691,7 +697,7 @@ static void cmd_dc(int dev_id, int argc, char **argv) int opt, dd; for_each_opt(opt, dc_options, NULL) { - switch(opt) { + switch (opt) { default: printf(dc_help); return; @@ -732,7 +738,8 @@ static void cmd_dc(int dev_id, int argc, char **argv) exit(1); } - if (hci_disconnect(dd, htobs(cr->conn_info->handle), HCI_OE_USER_ENDED_CONNECTION, 10000) < 0) + if (hci_disconnect(dd, htobs(cr->conn_info->handle), + HCI_OE_USER_ENDED_CONNECTION, 10000) < 0) perror("Disconnect failed"); close(dd); @@ -757,7 +764,7 @@ static void cmd_sr(int dev_id, int argc, char **argv) int opt, dd; for_each_opt(opt, sr_options, NULL) { - switch(opt) { + switch (opt) { default: printf(sr_help); return; @@ -827,7 +834,7 @@ static void cmd_rssi(int dev_id, int argc, char **argv) int opt, dd; for_each_opt(opt, rssi_options, NULL) { - switch(opt) { + switch (opt) { default: printf(rssi_help); return; @@ -884,7 +891,8 @@ static void cmd_rssi(int dev_id, int argc, char **argv) } if (rp.status) { - printf("Read RSSI returned (error) status 0x%2.2X\n", rp.status); + printf("Read RSSI returned (error) status 0x%2.2X\n", + rp.status); exit(1); } printf("RSSI return value: %d\n", rp.rssi); @@ -914,7 +922,7 @@ static void cmd_lq(int dev_id, int argc, char **argv) int opt, dd; for_each_opt(opt, lq_options, NULL) { - switch(opt) { + switch (opt) { default: printf(lq_help); return; @@ -971,7 +979,7 @@ static void cmd_lq(int dev_id, int argc, char **argv) } if (rp.status) { - fprintf(stderr, "HCI get_link_quality cmd failed (0x%2.2X)\n", + fprintf(stderr, "HCI get_link_quality cmd failed (0x%2.2X)\n", rp.status); exit(1); } @@ -1002,7 +1010,7 @@ static void cmd_tpl(int dev_id, int argc, char **argv) int opt, dd; for_each_opt(opt, tpl_options, NULL) { - switch(opt) { + switch (opt) { default: printf(tpl_help); return; @@ -1091,7 +1099,7 @@ static void cmd_afh(int dev_id, int argc, char **argv) int opt, dd; for_each_opt(opt, afh_options, NULL) { - switch(opt) { + switch (opt) { default: printf(afh_help); return; @@ -1148,7 +1156,7 @@ static void cmd_afh(int dev_id, int argc, char **argv) } if (rp.status) { - fprintf(stderr, "HCI read_afh_map cmd failed (0x%2.2X)\n", + fprintf(stderr, "HCI read_afh_map cmd failed (0x%2.2X)\n", rp.status); exit(1); } @@ -1187,7 +1195,7 @@ static void cmd_cpt(int dev_id, int argc, char **argv) int opt, dd, ptype; for_each_opt(opt, cpt_options, NULL) { - switch(opt) { + switch (opt) { default: printf(cpt_help); return; @@ -1272,7 +1280,7 @@ static void cmd_lst(int dev_id, int argc, char **argv) int opt, dd; for_each_opt(opt, lst_options, NULL) { - switch(opt) { + switch (opt) { default: printf(lst_help); return; @@ -1377,7 +1385,7 @@ static void cmd_auth(int dev_id, int argc, char **argv) int opt, dd; for_each_opt(opt, auth_options, NULL) { - switch(opt) { + switch (opt) { default: printf(auth_help); return; @@ -1446,7 +1454,7 @@ static void cmd_enc(int dev_id, int argc, char **argv) int opt, dd; for_each_opt(opt, enc_options, NULL) { - switch(opt) { + switch (opt) { default: printf(enc_help); return; @@ -1535,7 +1543,7 @@ static void usage(void) "\t--help\tDisplay help\n" "\t-i dev\tHCI device\n"); printf("Commands:\n"); - for (i=0; command[i].cmd; i++) + for (i = 0; command[i].cmd; i++) printf("\t%-4s\t%s\n", command[i].cmd, command[i].doc); printf("\n" @@ -1544,8 +1552,8 @@ static void usage(void) } static struct option main_options[] = { - {"help", 0,0, 'h'}, - {"device", 1,0, 'i'}, + {"help", 0,0, 'h'}, + {"device", 1,0, 'i'}, {0, 0, 0, 0} }; @@ -1555,7 +1563,7 @@ int main(int argc, char **argv) bdaddr_t ba; while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { - switch(opt) { + switch (opt) { case 'i': dev_id = hci_devid(optarg); if (dev_id < 0) { @@ -1585,7 +1593,7 @@ int main(int argc, char **argv) exit(1); } - for (i=0; command[i].cmd; i++) { + for (i = 0; command[i].cmd; i++) { if (strncmp(command[i].cmd, argv[0], 3)) continue; command[i].func(dev_id, argc, argv); -- cgit From 5327e84a4c0f07e44d8c3b23410c355465b094e5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 4 Nov 2004 11:23:01 +0000 Subject: Add support for changing the link key of a connection --- tools/hcitool.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 6c41483b..4ecead2f 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1506,6 +1506,74 @@ static void cmd_enc(int dev_id, int argc, char **argv) free(cr); } +/* Change connection link key */ + +static struct option key_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *key_help = + "Usage:\n" + "\tkey \n"; + +static void cmd_key(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + bdaddr_t bdaddr; + int opt, dd; + + for_each_opt(opt, key_options, NULL) { + switch (opt) { + default: + printf(key_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(key_help); + return; + } + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + if (hci_change_link_key(dd, htobs(cr->conn_info->handle), 25000) < 0) { + perror("Changing link key failed"); + exit(1); + } + + close(dd); + free(cr); +} + static struct { char *cmd; void (*func)(int dev_id, int argc, char **argv); @@ -1529,6 +1597,7 @@ static struct { { "lst", cmd_lst, "Set/display link supervision timeout" }, { "auth", cmd_auth, "Request authentication" }, { "enc", cmd_enc, "Set connection encryption" }, + { "key", cmd_key, "Change connection link key" }, { NULL, NULL, 0 } }; -- cgit From 1fc62ff85f185eae7f2297648fc9a2846fcb284d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 9 Nov 2004 22:55:42 +0000 Subject: Use the new AFH functions --- tools/hcitool.c | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 4ecead2f..8bb68427 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1092,10 +1092,9 @@ static char *afh_help = static void cmd_afh(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; - struct hci_request rq; - read_afh_map_rp rp; bdaddr_t bdaddr; uint16_t handle; + uint8_t mode, map[10]; int opt, dd; for_each_opt(opt, afh_options, NULL) { @@ -1142,30 +1141,16 @@ static void cmd_afh(int dev_id, int argc, char **argv) handle = htobs(cr->conn_info->handle); - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_STATUS_PARAM; - rq.ocf = OCF_READ_AFH_MAP; - rq.cparam = &handle; - rq.clen = 2; - rq.rparam = &rp; - rq.rlen = READ_AFH_MAP_RP_SIZE; - - if (hci_send_req(dd, &rq, 100) < 0) { + if (hci_read_afh_map(dd, handle, &mode, map, 1000) < 0) { perror("HCI read AFH map request failed"); exit(1); } - if (rp.status) { - fprintf(stderr, "HCI read_afh_map cmd failed (0x%2.2X)\n", - rp.status); - exit(1); - } - - if (rp.mode == 0x01) { + if (mode == 0x01) { int i; printf("AFH map: 0x"); for (i = 0; i < 10; i++) - printf("%02x", rp.map[i]); + printf("%02x", map[i]); printf("\n"); } else printf("AFH disabled\n"); -- cgit From 018d2a9255e4015860825bd4957d5bd41ba7cecc Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 11 Jan 2005 13:21:30 +0000 Subject: Whitespace cleanup and make more code static --- tools/hcitool.c | 154 ++++++++++++++++++++++++++------------------------------ 1 file changed, 71 insertions(+), 83 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 8bb68427..99262f41 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -33,36 +33,24 @@ #endif #include -#include -#include -#include -#include -#include #include -#include - -#include -#include +#include +#include #include -#include #include #include -#include #include #include #include -extern int optind,opterr,optopt; -extern char *optarg; - #define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, NULL)) != -1) static void usage(void); static int dev_info(int s, int dev_id, long arg) { - struct hci_dev_info di = {dev_id: dev_id}; + struct hci_dev_info di = { dev_id: dev_id }; char addr[18]; if (ioctl(s, HCIGETDEVINFO, (void *) &di)) @@ -155,11 +143,11 @@ static void hex_dump(char *pref, int width, unsigned char *buf, int len) /* Display local devices */ static struct option dev_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + {0, 0, 0, 0 } }; -static char *dev_help = +static char *dev_help = "Usage:\n" "\tdev\n"; @@ -181,14 +169,14 @@ static void cmd_dev(int dev_id, int argc, char **argv) /* Inquiry */ static struct option inq_options[] = { - {"help", 0,0, 'h'}, - {"length", 1,0, 'l'}, - {"numrsp", 1,0, 'n'}, - {"flush", 0,0, 'f'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { "length", 1, 0, 'l' }, + { "numrsp", 1, 0, 'n' }, + { "flush", 0, 0, 'f' }, + { 0, 0, 0, 0 } }; -static char *inq_help = +static char *inq_help = "Usage:\n" "\tinq [--length=N] maximum inquiry duration in 1.28 s units\n" "\t [--numrsp=N] specify maximum number of inquiry responses\n" @@ -246,14 +234,14 @@ static void cmd_inq(int dev_id, int argc, char **argv) /* Device scanning */ static struct option scan_options[] = { - {"help", 0,0, 'h'}, - {"length", 1,0, 'l'}, - {"numrsp", 1,0, 'n'}, - {"flush", 0,0, 'f'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { "length", 1, 0, 'l' }, + { "numrsp", 1, 0, 'n' }, + { "flush", 0, 0, 'f' }, + { 0, 0, 0, 0 } }; -static char *scan_help = +static char *scan_help = "Usage:\n" "\tscan [--length=N] [--numrsp=N] [--flush]\n"; @@ -326,8 +314,8 @@ static void cmd_scan(int dev_id, int argc, char **argv) /* Remote name */ static struct option name_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; static char *name_help = @@ -380,11 +368,11 @@ static void cmd_name(int dev_id, int argc, char **argv) /* Info about remote device */ static struct option info_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *info_help = +static char *info_help = "Usage:\n" "\tinfo \n"; @@ -494,11 +482,11 @@ static void cmd_info(int dev_id, int argc, char **argv) /* Send arbitrary HCI commands */ static struct option cmd_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *cmd_help = +static char *cmd_help = "Usage:\n" "\tcmd [parameters]\n" "Example:\n" @@ -584,11 +572,11 @@ static void cmd_cmd(int dev_id, int argc, char **argv) /* Display active connections */ static struct option con_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *con_help = +static char *con_help = "Usage:\n" "\tcon\n"; @@ -611,13 +599,13 @@ static void cmd_con(int dev_id, int argc, char **argv) /* Create connection */ static struct option cc_options[] = { - {"help", 0,0, 'h'}, - {"role", 1,0, 'r'}, - {"ptype", 1,0, 'p'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { "role", 1, 0, 'r' }, + { "ptype", 1, 0, 'p' }, + { 0, 0, 0, 0 } }; -static char *cc_help = +static char *cc_help = "Usage:\n" "\tcc [--role=m|s] [--ptype=pkt_types] \n" "Example:\n" @@ -682,11 +670,11 @@ static void cmd_cc(int dev_id, int argc, char **argv) /* Close connection */ static struct option dc_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *dc_help = +static char *dc_help = "Usage:\n" "\tdc \n"; @@ -749,11 +737,11 @@ static void cmd_dc(int dev_id, int argc, char **argv) /* Role switch */ static struct option sr_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *sr_help = +static char *sr_help = "Usage:\n" "\tsr \n"; @@ -816,11 +804,11 @@ static void cmd_sr(int dev_id, int argc, char **argv) /* Read RSSI */ static struct option rssi_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *rssi_help = +static char *rssi_help = "Usage:\n" "\trssi \n"; @@ -904,11 +892,11 @@ static void cmd_rssi(int dev_id, int argc, char **argv) /* Get link quality */ static struct option lq_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *lq_help = +static char *lq_help = "Usage:\n" "\tlq \n"; @@ -992,11 +980,11 @@ static void cmd_lq(int dev_id, int argc, char **argv) /* Get transmit power level */ static struct option tpl_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *tpl_help = +static char *tpl_help = "Usage:\n" "\ttpl [type]\n"; @@ -1081,11 +1069,11 @@ static void cmd_tpl(int dev_id, int argc, char **argv) /* Get AFH channel map */ static struct option afh_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *afh_help = +static char *afh_help = "Usage:\n" "\tafh \n"; @@ -1162,11 +1150,11 @@ static void cmd_afh(int dev_id, int argc, char **argv) /* Set connection packet type */ static struct option cpt_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *cpt_help = +static char *cpt_help = "Usage:\n" "\tcpt \n"; @@ -1246,11 +1234,11 @@ static void cmd_cpt(int dev_id, int argc, char **argv) /* Get/Set link supervision timeout */ static struct option lst_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *lst_help = +static char *lst_help = "Usage:\n" "\tlst [new value in slots]\n"; @@ -1355,11 +1343,11 @@ static void cmd_lst(int dev_id, int argc, char **argv) /* Request authentication */ static struct option auth_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *auth_help = +static char *auth_help = "Usage:\n" "\tauth \n"; @@ -1423,11 +1411,11 @@ static void cmd_auth(int dev_id, int argc, char **argv) /* Activate encryption */ static struct option enc_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *enc_help = +static char *enc_help = "Usage:\n" "\tenc [encrypt enable]\n"; @@ -1494,11 +1482,11 @@ static void cmd_enc(int dev_id, int argc, char **argv) /* Change connection link key */ static struct option key_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *key_help = +static char *key_help = "Usage:\n" "\tkey \n"; @@ -1606,9 +1594,9 @@ static void usage(void) } static struct option main_options[] = { - {"help", 0,0, 'h'}, - {"device", 1,0, 'i'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { "device", 1, 0, 'i' }, + { 0, 0, 0, 0 } }; int main(int argc, char **argv) -- cgit From 818f37527b66b1bd8c177759a8c7710882030093 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 13 Jan 2005 20:21:51 +0000 Subject: Use library functions for RSSI and link quality --- tools/hcitool.c | 48 +++++++----------------------------------------- 1 file changed, 7 insertions(+), 41 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 99262f41..ffa98536 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -815,10 +815,8 @@ static char *rssi_help = static void cmd_rssi(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; - struct hci_request rq; - read_rssi_rp rp; bdaddr_t bdaddr; - uint16_t handle; + int8_t rssi; int opt, dd; for_each_opt(opt, rssi_options, NULL) { @@ -863,27 +861,12 @@ static void cmd_rssi(int dev_id, int argc, char **argv) exit(1); } - handle = htobs(cr->conn_info->handle); - - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_STATUS_PARAM; - rq.ocf = OCF_READ_RSSI; - rq.cparam = &handle; - rq.clen = 2; - rq.rparam = &rp; - rq.rlen = READ_RSSI_RP_SIZE; - - if (hci_send_req(dd, &rq, 100) < 0) { + if (hci_read_rssi(dd, htobs(cr->conn_info->handle), &rssi, 1000) < 0) { perror("Read RSSI failed"); exit(1); } - if (rp.status) { - printf("Read RSSI returned (error) status 0x%2.2X\n", - rp.status); - exit(1); - } - printf("RSSI return value: %d\n", rp.rssi); + printf("RSSI return value: %d\n", rssi); close(dd); free(cr); @@ -903,10 +886,8 @@ static char *lq_help = static void cmd_lq(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; - struct hci_request rq; - get_link_quality_rp rp; bdaddr_t bdaddr; - uint16_t handle; + uint8_t lq; int opt, dd; for_each_opt(opt, lq_options, NULL) { @@ -951,27 +932,12 @@ static void cmd_lq(int dev_id, int argc, char **argv) exit(1); } - handle = htobs(cr->conn_info->handle); - - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_STATUS_PARAM; - rq.ocf = OCF_GET_LINK_QUALITY; - rq.cparam = &handle; - rq.clen = 2; - rq.rparam = &rp; - rq.rlen = GET_LINK_QUALITY_RP_SIZE; - - if (hci_send_req(dd, &rq, 100) < 0) { - perror("HCI get_link_quality request failed"); + if (hci_read_link_quality(dd, htobs(cr->conn_info->handle), &lq, 1000) < 0) { + perror("HCI read_link_quality request failed"); exit(1); } - if (rp.status) { - fprintf(stderr, "HCI get_link_quality cmd failed (0x%2.2X)\n", - rp.status); - exit(1); - } - printf("Link quality: %d\n", rp.link_quality); + printf("Link quality: %d\n", lq); close(dd); free(cr); -- cgit From 1b71ff969ad17bd4e1265b6cc1d06ca38afc6c27 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 13 Jan 2005 22:48:24 +0000 Subject: Use library function for link supervision timeout --- tools/hcitool.c | 39 ++++++++------------------------------- 1 file changed, 8 insertions(+), 31 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index ffa98536..8aef142b 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1211,11 +1211,8 @@ static char *lst_help = static void cmd_lst(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; - struct hci_request rq; - read_link_supervision_timeout_rp rp; - write_link_supervision_timeout_cp cp; bdaddr_t bdaddr; - uint16_t handle; + uint16_t timeout; int opt, dd; for_each_opt(opt, lst_options, NULL) { @@ -1260,43 +1257,23 @@ static void cmd_lst(int dev_id, int argc, char **argv) exit(1); } - handle = htobs(cr->conn_info->handle); - if (argc == 1) { - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_READ_LINK_SUPERVISION_TIMEOUT; - rq.cparam = &handle; - rq.clen = 2; - rq.rparam = &rp; - rq.rlen = READ_LINK_SUPERVISION_TIMEOUT_RP_SIZE; - - if (hci_send_req(dd, &rq, 100) < 0) { + if (hci_read_link_supervision_timeout(dd, htobs(cr->conn_info->handle), &timeout, 1000) < 0) { perror("HCI read_link_supervision_timeout request failed"); exit(1); } - if (rp.status) { - fprintf(stderr, "HCI read_link_supervision_timeout failed (0x%2.2X)\n", - rp.status); - exit(1); - } - if (rp.link_sup_to) + timeout = btohs(timeout); + + if (timeout) printf("Link supervision timeout: %u slots (%.2f msec)\n", - rp.link_sup_to, (float)rp.link_sup_to * 0.625); + timeout, (float) timeout * 0.625); else printf("Link supervision timeout never expires\n"); } else { - cp.handle = htobs(cr->conn_info->handle); - cp.link_sup_to = strtol(argv[1], NULL, 10); - - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_WRITE_LINK_SUPERVISION_TIMEOUT; - rq.cparam = &cp; - rq.clen = WRITE_LINK_SUPERVISION_TIMEOUT_CP_SIZE; + timeout = btohs(strtol(argv[1], NULL, 10)); - if (hci_send_req(dd, &rq, 100) < 0) { + if (hci_write_link_supervision_timeout(dd, htobs(cr->conn_info->handle), timeout, 1000) < 0) { perror("HCI write_link_supervision_timeout request failed"); exit(1); } -- cgit From cbbc9f09bb9b41caa5ee9fa751a80d16d34a4bda Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 13 Jan 2005 22:58:13 +0000 Subject: Use library function for reading the transmit power level --- tools/hcitool.c | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 8aef142b..7d965dd6 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -957,10 +957,8 @@ static char *tpl_help = static void cmd_tpl(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; - struct hci_request rq; - read_transmit_power_level_cp cp; - read_transmit_power_level_rp rp; bdaddr_t bdaddr; + uint8_t type, level; int opt, dd; for_each_opt(opt, tpl_options, NULL) { @@ -979,7 +977,7 @@ static void cmd_tpl(int dev_id, int argc, char **argv) } str2ba(argv[0], &bdaddr); - cp.type = (argc > 1) ? atoi(argv[1]) : 0; + type = (argc > 1) ? atoi(argv[1]) : 0; if (dev_id < 0) { dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); @@ -1005,28 +1003,14 @@ static void cmd_tpl(int dev_id, int argc, char **argv) perror("Get connection info failed"); exit(1); } - cp.handle = htobs(cr->conn_info->handle); - - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_READ_TRANSMIT_POWER_LEVEL; - rq.cparam = &cp; - rq.clen = READ_TRANSMIT_POWER_LEVEL_CP_SIZE; - rq.rparam = &rp; - rq.rlen = READ_TRANSMIT_POWER_LEVEL_RP_SIZE; - if (hci_send_req(dd, &rq, 100) < 0) { + if (hci_read_transmit_power_level(dd, htobs(cr->conn_info->handle), type, &level, 1000) < 0) { perror("HCI read transmit power level request failed"); exit(1); } - if (rp.status) { - fprintf(stderr, "HCI read_transmit_power_level cmd failed (0x%2.2X)\n", - rp.status); - exit(1); - } printf("%s transmit power level: %d\n", - (cp.type == 0) ? "Current" : "Maximum", rp.level); + (type == 0) ? "Current" : "Maximum", level); close(dd); free(cr); -- cgit From fefb12aae57e186c00a50a87a3725f8657fd95e2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 25 Jan 2005 02:46:59 +0000 Subject: Add command for reading the clock offset --- tools/hcitool.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 91 insertions(+), 19 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 7d965dd6..9f69ed01 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1474,30 +1474,102 @@ static void cmd_key(int dev_id, int argc, char **argv) free(cr); } +/* Read clock offset */ + +static struct option clkoff_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static char *clkoff_help = + "Usage:\n" + "\tclkoff \n"; + +static void cmd_clkoff(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + bdaddr_t bdaddr; + uint16_t offset; + int opt, dd; + + for_each_opt(opt, clkoff_options, NULL) { + switch (opt) { + default: + printf(clkoff_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(clkoff_help); + return; + } + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + if (hci_read_clock_offset(dd, htobs(cr->conn_info->handle), &offset, 1000) < 0) { + perror("Reading clock offset failed"); + exit(1); + } + + printf("Clock offset: 0x%4.4x\n", btohs(offset)); + + close(dd); + free(cr); +} + static struct { char *cmd; void (*func)(int dev_id, int argc, char **argv); char *doc; } command[] = { - { "dev", cmd_dev, "Display local devices" }, - { "inq", cmd_inq, "Inquire remote devices" }, - { "scan", cmd_scan, "Scan for remote devices" }, - { "name", cmd_name, "Get name from remote device" }, - { "info", cmd_info, "Get information from remote device" }, - { "cmd", cmd_cmd, "Submit arbitrary HCI commands" }, - { "con", cmd_con, "Display active connections" }, - { "cc", cmd_cc, "Create connection to remote device" }, - { "dc", cmd_dc, "Disconnect from remote device" }, - { "sr", cmd_sr, "Switch master/slave role" }, - { "cpt", cmd_cpt, "Change connection packet type" }, - { "rssi", cmd_rssi, "Display connection RSSI" }, - { "lq", cmd_lq, "Display link quality" }, - { "tpl", cmd_tpl, "Display transmit power level" }, - { "afh", cmd_afh, "Display AFH channel map" }, - { "lst", cmd_lst, "Set/display link supervision timeout" }, - { "auth", cmd_auth, "Request authentication" }, - { "enc", cmd_enc, "Set connection encryption" }, - { "key", cmd_key, "Change connection link key" }, + { "dev", cmd_dev, "Display local devices" }, + { "inq", cmd_inq, "Inquire remote devices" }, + { "scan", cmd_scan, "Scan for remote devices" }, + { "name", cmd_name, "Get name from remote device" }, + { "info", cmd_info, "Get information from remote device" }, + { "cmd", cmd_cmd, "Submit arbitrary HCI commands" }, + { "con", cmd_con, "Display active connections" }, + { "cc", cmd_cc, "Create connection to remote device" }, + { "dc", cmd_dc, "Disconnect from remote device" }, + { "sr", cmd_sr, "Switch master/slave role" }, + { "cpt", cmd_cpt, "Change connection packet type" }, + { "rssi", cmd_rssi, "Display connection RSSI" }, + { "lq", cmd_lq, "Display link quality" }, + { "tpl", cmd_tpl, "Display transmit power level" }, + { "afh", cmd_afh, "Display AFH channel map" }, + { "lst", cmd_lst, "Set/display link supervision timeout" }, + { "auth", cmd_auth, "Request authentication" }, + { "enc", cmd_enc, "Set connection encryption" }, + { "key", cmd_key, "Change connection link key" }, + { "clkoff", cmd_clkoff, "Read clock offset" }, { NULL, NULL, 0 } }; -- cgit From 30fa99ad8cc79b6e4cb4620a31510d5a6cd31acd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 25 Jan 2005 21:41:40 +0000 Subject: Add command for reading the clock --- tools/hcitool.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 9f69ed01..8b7131a0 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1545,6 +1545,84 @@ static void cmd_clkoff(int dev_id, int argc, char **argv) free(cr); } +/* Read clock */ + +static struct option clock_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static char *clock_help = + "Usage:\n" + "\tclock [which clock]\n"; + +static void cmd_clock(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + bdaddr_t bdaddr; + uint8_t which; + uint32_t clock; + uint16_t accuracy; + int opt, dd; + + for_each_opt(opt, clock_options, NULL) { + switch (opt) { + default: + printf(clock_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(clock_help); + return; + } + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + which = (argc > 1) ? atoi(argv[1]) : 0x01; + + if (hci_read_clock(dd, htobs(cr->conn_info->handle), which, &clock, &accuracy, 1000) < 0) { + perror("Reading clock failed"); + exit(1); + } + + accuracy = btohs(accuracy); + + printf("Clock: 0x%4.4x\n", btohl(clock)); + printf("Accuracy: %.2f msec\n", (float) accuracy * 0.3125); + + close(dd); + free(cr); +} + static struct { char *cmd; void (*func)(int dev_id, int argc, char **argv); @@ -1570,6 +1648,7 @@ static struct { { "enc", cmd_enc, "Set connection encryption" }, { "key", cmd_key, "Change connection link key" }, { "clkoff", cmd_clkoff, "Read clock offset" }, + { "clock", cmd_clock, "Read local or remote clock" }, { NULL, NULL, 0 } }; -- cgit From d67817be8163beb8d69d97934eb998d269221a14 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Feb 2005 04:17:52 +0000 Subject: Use the clock offset when getting the remote names --- tools/hcitool.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 8b7131a0..57d23e6a 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -301,7 +301,8 @@ static void cmd_scan(int dev_id, int argc, char **argv) for (i = 0; i < num_rsp; i++) { memset(name, 0, sizeof(name)); - if (hci_read_remote_name(dd, &(info+i)->bdaddr, sizeof(name), name, 100000) < 0) + if (hci_read_remote_name_with_clock_offset(dd, &(info+i)->bdaddr, + htobs((info+i)->clock_offset), sizeof(name), name, 100000) < 0) strcpy(name, "n/a"); ba2str(&(info+i)->bdaddr, addr); printf("\t%s\t%s\n", addr, name); @@ -662,7 +663,7 @@ static void cmd_cc(int dev_id, int argc, char **argv) } if (hci_create_connection(dd, &bdaddr, htobs(ptype), - 0, role, &handle, 25000) < 0) + htobs(0x0000), role, &handle, 25000) < 0) perror("Can't create connection"); hci_close_dev(dd); } -- cgit From 8aebcde5f68394bc2cd27855971d26ce52da0500 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Feb 2005 05:02:24 +0000 Subject: Handle the valid bit of the clock offset --- tools/hcitool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 57d23e6a..766c084e 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -223,7 +223,7 @@ static void cmd_inq(int dev_id, int argc, char **argv) for (i = 0; i < num_rsp; i++) { ba2str(&(info+i)->bdaddr, addr); printf("\t%s\tclock offset: 0x%4.4x\tclass: 0x%2.2x%2.2x%2.2x\n", - addr, (info+i)->clock_offset, + addr, btohs((info+i)->clock_offset), (info+i)->dev_class[2], (info+i)->dev_class[1], (info+i)->dev_class[0]); @@ -302,7 +302,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) for (i = 0; i < num_rsp; i++) { memset(name, 0, sizeof(name)); if (hci_read_remote_name_with_clock_offset(dd, &(info+i)->bdaddr, - htobs((info+i)->clock_offset), sizeof(name), name, 100000) < 0) + (info+i)->clock_offset | 0x8000, sizeof(name), name, 100000) < 0) strcpy(name, "n/a"); ba2str(&(info+i)->bdaddr, addr); printf("\t%s\t%s\n", addr, name); -- cgit From 05ec11bf58edbacb68ebf4cd4b629df697224d6e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 22 Feb 2005 02:41:02 +0000 Subject: The transmit power level is a signed integer value --- tools/hcitool.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 766c084e..225977b7 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -959,7 +959,8 @@ static void cmd_tpl(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; bdaddr_t bdaddr; - uint8_t type, level; + uint8_t type; + int8_t level; int opt, dd; for_each_opt(opt, tpl_options, NULL) { -- cgit From 354b825e585790a15fc07ca382540739cbb3c155 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 22 Feb 2005 15:11:32 +0000 Subject: Use pscan_rep_mode for the name resolve --- tools/hcitool.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 225977b7..27ac78b7 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -302,7 +302,9 @@ static void cmd_scan(int dev_id, int argc, char **argv) for (i = 0; i < num_rsp; i++) { memset(name, 0, sizeof(name)); if (hci_read_remote_name_with_clock_offset(dd, &(info+i)->bdaddr, - (info+i)->clock_offset | 0x8000, sizeof(name), name, 100000) < 0) + (info+i)->pscan_rep_mode, + (info+i)->clock_offset | 0x8000, + sizeof(name), name, 100000) < 0) strcpy(name, "n/a"); ba2str(&(info+i)->bdaddr, addr); printf("\t%s\t%s\n", addr, name); -- cgit From 8e8b4632526b90c9a8a86d1829ee5b71033d3fbb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 27 Mar 2005 19:19:52 +0000 Subject: Add new search command and OUI support --- tools/hcitool.c | 314 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 310 insertions(+), 4 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 27ac78b7..9c4dc468 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -44,6 +44,8 @@ #include #include +#include "oui.h" + #define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, NULL)) != -1) static void usage(void); @@ -224,8 +226,8 @@ static void cmd_inq(int dev_id, int argc, char **argv) ba2str(&(info+i)->bdaddr, addr); printf("\t%s\tclock offset: 0x%4.4x\tclass: 0x%2.2x%2.2x%2.2x\n", addr, btohs((info+i)->clock_offset), - (info+i)->dev_class[2], - (info+i)->dev_class[1], + (info+i)->dev_class[2], + (info+i)->dev_class[1], (info+i)->dev_class[0]); } free(info); @@ -250,7 +252,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) inquiry_info *info = NULL; int num_rsp, length, flags; char addr[18]; - char name[248]; + char name[249]; int i, opt, dd; length = 8; /* ~10 seconds */ @@ -383,7 +385,7 @@ static void cmd_info(int dev_id, int argc, char **argv) { bdaddr_t bdaddr; uint16_t handle; - char name[248]; + char name[249], oui[9], *comp; unsigned char features[8]; struct hci_version version; struct hci_dev_info di; @@ -454,6 +456,13 @@ static void cmd_info(int dev_id, int argc, char **argv) printf("\tBD Address: %s\n", argv[0]); + ba2oui(&bdaddr, oui); + comp = ouitocomp(oui); + if (comp) { + printf("\tOUI Company: %s (%s)\n", comp, oui); + free(comp); + } + if (hci_read_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0) printf("\tDevice Name: %s\n", name); @@ -482,6 +491,302 @@ static void cmd_info(int dev_id, int argc, char **argv) close(dd); } +/* Find remote devices */ + +static struct option find_options[] = { + { "help", 0, 0, 'h' }, + { "length", 1, 0, 'l' }, + { "numrsp", 1, 0, 'n' }, + { "flush", 0, 0, 'f' }, + { 0, 0, 0, 0 } +}; + +static char *find_help = + "Usage:\n" + "\tfind [--length=N] [--numrsp=N] [--flush]\n"; + +static char *get_minor_device_name(int major, int minor) +{ + switch (major) { + case 0: /* misc */ + return ""; + case 1: /* computer */ + switch(minor) { + case 0: + return "Uncategorized"; + case 1: + return "Desktop workstation"; + case 2: + return "Server"; + case 3: + return "Laptop"; + case 4: + return "Handheld"; + case 5: + return "Palm"; + case 6: + return "Wearable"; + } + break; + case 2: /* phone */ + switch(minor) { + case 0: + return "Uncategorized"; + case 1: + return "Cellular"; + case 2: + return "Cordless"; + case 3: + return "Smart phone"; + case 4: + return "Wired modem or voice gateway"; + case 5: + return "Common ISDN Access"; + case 6: + return "Sim Card Reader"; + } + break; + case 3: /* lan access */ + if (minor == 0) + return "Uncategorized"; + switch(minor / 8) { + case 0: + return "Fully available"; + case 1: + return "1-17% utilized"; + case 2: + return "17-33% utilized"; + case 3: + return "33-50% utilized"; + case 4: + return "50-67% utilized"; + case 5: + return "67-83% utilized"; + case 6: + return "83-99% utilized"; + case 7: + return "No service available"; + } + break; + case 4: /* audio/video */ + switch(minor) { + case 0: + return "Uncategorized"; + case 1: + return "Device conforms to the Headset profile"; + case 2: + return "Hands-free"; + /* 3 is reserved */ + case 4: + return "Microphone"; + case 5: + return "Loudspeaker"; + case 6: + return "Headphones"; + case 7: + return "Portable Audio"; + case 8: + return "Car Audio"; + case 9: + return "Set-top box"; + case 10: + return "HiFi Audio Device"; + case 11: + return "VCR"; + case 12: + return "Video Camera"; + case 13: + return "Camcorder"; + case 14: + return "Video Monitor"; + case 15: + return "Video Display and Loudspeaker"; + case 16: + return "Video Conferencing"; + /* 17 is reserved */ + case 18: + return "Gaming/Toy"; + } + break; + case 5: /* peripheral */ + switch(minor) { + case 16: + return "Keyboard"; + case 32: + return "Pointing device"; + case 48: + return "Combo keyboard/pointing device"; + } + break; + case 6: /* imaging */ + if (minor & 4) + return "Display"; + if (minor & 8) + return "Camera"; + if (minor & 16) + return "Scanner"; + if (minor & 32) + return "Printer"; + break; + case 63: /* uncategorised */ + return ""; + } + return "Unknown (reserved) minor device class"; +} + +static char *major_classes[] = { + "Miscellaneous", "Computer", "Phone", "LAN Access", + "Audio/Video", "Peripheral", "Imaging", "Uncategorized" +}; + +static void cmd_find(int dev_id, int argc, char **argv) +{ + inquiry_info *info = NULL; + int num_rsp, length, flags; + uint8_t cls[3]; + uint16_t handle; + char addr[18], name[249], oui[9], *comp; + unsigned char features[8]; + struct hci_version version; + struct hci_dev_info di; + struct hci_conn_info_req *cr; + int i, opt, dd, cc = 0; + + length = 8; /* ~10 seconds */ + num_rsp = 100; + flags = 0; + + for_each_opt(opt, find_options, NULL) { + switch (opt) { + case 'l': + length = atoi(optarg); + break; + + case 'n': + num_rsp = atoi(optarg); + break; + + case 'f': + flags |= IREQ_CACHE_FLUSH; + break; + + default: + printf(find_help); + return; + } + } + + if (dev_id < 0) { + dev_id = hci_get_route(NULL); + if (dev_id < 0) { + perror("Device is not available"); + exit(1); + } + } + + if (hci_devinfo(dev_id, &di) < 0) { + perror("Can't get device info"); + exit(1); + } + + printf("Searching ...\n"); + num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); + if (num_rsp < 0) { + perror("Inquiry failed"); + exit(1); + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + free(info); + exit(1); + } + + printf("\n"); + + for (i = 0; i < num_rsp; i++) { + ba2str(&(info+i)->bdaddr, addr); + printf("BD Address:\t%s [mode %d, clkoffset 0x%4.4x]\n", addr, + (info+i)->pscan_rep_mode, btohs((info+i)->clock_offset)); + + ba2oui(&(info+i)->bdaddr, oui); + comp = ouitocomp(oui); + if (comp) { + printf("OUI company:\t%s (%s)\n", comp, oui); + free(comp); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (cr) { + bacpy(&cr->bdaddr, &(info+i)->bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + if (hci_create_connection(dd, &(info+i)->bdaddr, + htobs(di.pkt_type & ACL_PTYPE_MASK), + (info+i)->clock_offset | 0x8000, + 0x01, &handle, 25000) < 0) + handle = 0; + else + cc = 1; + } else + handle = htobs(cr->conn_info->handle); + } else + handle = 0; + + memset(name, 0, sizeof(name)); + if (hci_read_remote_name_with_clock_offset(dd, &(info+i)->bdaddr, + (info+i)->pscan_rep_mode, + (info+i)->clock_offset | 0x8000, + sizeof(name), name, 100000) < 0) + strcpy(name, "n/a"); + printf("Device name:\t%s\n", name); + + memcpy(cls, (info+i)->dev_class, 3); + printf("Device class:\t"); + if ((cls[1] & 0x1f) > sizeof(*major_classes)) + printf("Invalid"); + else + printf("%s, %s", major_classes[cls[1] & 0x1f], + get_minor_device_name(cls[1] & 0x1f, cls[0] >> 2)); + printf(" (0x%2.2x%2.2x%2.2x)\n", cls[2], cls[1], cls[0]); + + if (handle > 0) { + if (hci_read_remote_version(dd, handle, &version, 20000) == 0) { + printf("Manufacturer:\t%s (%d)\n", + bt_compidtostr(version.manufacturer), + version.manufacturer); + printf("LMP version:\t%s (0x%x) [subver 0x%x]\n", + lmp_vertostr(version.lmp_ver), + version.lmp_ver, version.lmp_subver); + } + + if (hci_read_remote_features(dd, handle, features, 20000) == 0) { + printf("LMP features:\t0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x" + " 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", + features[0], features[1], + features[2], features[3], + features[4], features[5], + features[6], features[7]); + printf("%s\n", lmp_featurestostr(features, "\t\t", 63)); + } + + if (cc) { + usleep(10000); + hci_disconnect(dd, handle, HCI_OE_USER_ENDED_CONNECTION, 10000); + } + } + + printf("\n"); + + if (cr) + free(cr); + } + + close(dd); + free(info); +} + /* Send arbitrary HCI commands */ static struct option cmd_options[] = { @@ -1637,6 +1942,7 @@ static struct { { "scan", cmd_scan, "Scan for remote devices" }, { "name", cmd_name, "Get name from remote device" }, { "info", cmd_info, "Get information from remote device" }, + { "find", cmd_find, "Search for remote devices" }, { "cmd", cmd_cmd, "Submit arbitrary HCI commands" }, { "con", cmd_con, "Display active connections" }, { "cc", cmd_cc, "Create connection to remote device" }, -- cgit From f1a83659170a8f324991061c9ed14f39393e7c10 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 11 Apr 2005 16:06:45 +0000 Subject: Integrate find options into scan command --- tools/hcitool.c | 572 ++++++++++++++++++++++++++------------------------------ 1 file changed, 269 insertions(+), 303 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 9c4dc468..9ac890fd 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -142,6 +142,140 @@ static void hex_dump(char *pref, int width, unsigned char *buf, int len) printf("\n"); } +static char *get_minor_device_name(int major, int minor) +{ + switch (major) { + case 0: /* misc */ + return ""; + case 1: /* computer */ + switch(minor) { + case 0: + return "Uncategorized"; + case 1: + return "Desktop workstation"; + case 2: + return "Server"; + case 3: + return "Laptop"; + case 4: + return "Handheld"; + case 5: + return "Palm"; + case 6: + return "Wearable"; + } + break; + case 2: /* phone */ + switch(minor) { + case 0: + return "Uncategorized"; + case 1: + return "Cellular"; + case 2: + return "Cordless"; + case 3: + return "Smart phone"; + case 4: + return "Wired modem or voice gateway"; + case 5: + return "Common ISDN Access"; + case 6: + return "Sim Card Reader"; + } + break; + case 3: /* lan access */ + if (minor == 0) + return "Uncategorized"; + switch(minor / 8) { + case 0: + return "Fully available"; + case 1: + return "1-17% utilized"; + case 2: + return "17-33% utilized"; + case 3: + return "33-50% utilized"; + case 4: + return "50-67% utilized"; + case 5: + return "67-83% utilized"; + case 6: + return "83-99% utilized"; + case 7: + return "No service available"; + } + break; + case 4: /* audio/video */ + switch(minor) { + case 0: + return "Uncategorized"; + case 1: + return "Device conforms to the Headset profile"; + case 2: + return "Hands-free"; + /* 3 is reserved */ + case 4: + return "Microphone"; + case 5: + return "Loudspeaker"; + case 6: + return "Headphones"; + case 7: + return "Portable Audio"; + case 8: + return "Car Audio"; + case 9: + return "Set-top box"; + case 10: + return "HiFi Audio Device"; + case 11: + return "VCR"; + case 12: + return "Video Camera"; + case 13: + return "Camcorder"; + case 14: + return "Video Monitor"; + case 15: + return "Video Display and Loudspeaker"; + case 16: + return "Video Conferencing"; + /* 17 is reserved */ + case 18: + return "Gaming/Toy"; + } + break; + case 5: /* peripheral */ + switch(minor) { + case 16: + return "Keyboard"; + case 32: + return "Pointing device"; + case 48: + return "Combo keyboard/pointing device"; + } + break; + case 6: /* imaging */ + if (minor & 4) + return "Display"; + if (minor & 8) + return "Camera"; + if (minor & 16) + return "Scanner"; + if (minor & 32) + return "Printer"; + break; + case 63: /* uncategorised */ + return ""; + } + return "Unknown (reserved) minor device class"; +} + +static char *major_classes[] = { + "Miscellaneous", "Computer", "Phone", "LAN Access", + "Audio/Video", "Peripheral", "Imaging", "Uncategorized" +}; + /* Display local devices */ static struct option dev_options[] = { @@ -240,20 +374,31 @@ static struct option scan_options[] = { { "length", 1, 0, 'l' }, { "numrsp", 1, 0, 'n' }, { "flush", 0, 0, 'f' }, + { "class", 0, 0, 'c' }, + { "info", 0, 0, 'i' }, + { "oui", 0, 0, 'o' }, + { "all", 0, 0, 'a' }, + { "ext", 0, 0, 'a' }, { 0, 0, 0, 0 } }; static char *scan_help = "Usage:\n" - "\tscan [--length=N] [--numrsp=N] [--flush]\n"; + "\tscan [--length=N] [--numrsp=N] [--flush] [--class] [--info] [--oui]\n"; static void cmd_scan(int dev_id, int argc, char **argv) { inquiry_info *info = NULL; int num_rsp, length, flags; - char addr[18]; - char name[249]; - int i, opt, dd; + uint8_t cls[3]; + uint16_t handle; + char addr[18], name[249], oui[9], *comp; + unsigned char features[8]; + struct hci_version version; + struct hci_dev_info di; + struct hci_conn_info_req *cr; + int extcls = 0, extinf = 0, extoui = 0; + int i, opt, dd, cc; length = 8; /* ~10 seconds */ num_rsp = 100; @@ -273,6 +418,24 @@ static void cmd_scan(int dev_id, int argc, char **argv) flags |= IREQ_CACHE_FLUSH; break; + case 'c': + extcls = 1; + break; + + case 'i': + extinf = 1; + break; + + case 'o': + extoui = 1; + break; + + case 'a': + extcls = 1; + extinf = 1; + extoui = 1; + break; + default: printf(scan_help); return; @@ -287,6 +450,11 @@ static void cmd_scan(int dev_id, int argc, char **argv) } } + if (hci_devinfo(dev_id, &di) < 0) { + perror("Can't get device info"); + exit(1); + } + printf("Scanning ...\n"); num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); if (num_rsp < 0) { @@ -301,15 +469,110 @@ static void cmd_scan(int dev_id, int argc, char **argv) exit(1); } + if (extcls || extinf || extoui) + printf("\n"); + for (i = 0; i < num_rsp; i++) { + if (!extcls && !extinf && !extoui) { + memset(name, 0, sizeof(name)); + if (hci_read_remote_name_with_clock_offset(dd, + &(info+i)->bdaddr, + (info+i)->pscan_rep_mode, + (info+i)->clock_offset | 0x8000, + sizeof(name), name, 100000) < 0) + strcpy(name, "n/a"); + ba2str(&(info+i)->bdaddr, addr); + printf("\t%s\t%s\n", addr, name); + continue; + } + + ba2str(&(info+i)->bdaddr, addr); + printf("BD Address:\t%s [mode %d, clkoffset 0x%4.4x]\n", addr, + (info+i)->pscan_rep_mode, btohs((info+i)->clock_offset)); + + if (extoui) { + ba2oui(&(info+i)->bdaddr, oui); + comp = ouitocomp(oui); + if (comp) { + printf("OUI company:\t%s (%s)\n", comp, oui); + free(comp); + } + } + + cc = 0; + + if (extinf) { + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (cr) { + bacpy(&cr->bdaddr, &(info+i)->bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + handle = 0; + cc = 1; + } else { + handle = htobs(cr->conn_info->handle); + cc = 0; + } + free(cr); + } + + if (cc) { + if (hci_create_connection(dd, &(info+i)->bdaddr, + htobs(di.pkt_type & ACL_PTYPE_MASK), + (info+i)->clock_offset | 0x8000, + 0x01, &handle, 25000) < 0) { + handle = 0; + cc = 0; + } + } + } + memset(name, 0, sizeof(name)); if (hci_read_remote_name_with_clock_offset(dd, &(info+i)->bdaddr, (info+i)->pscan_rep_mode, (info+i)->clock_offset | 0x8000, sizeof(name), name, 100000) < 0) strcpy(name, "n/a"); - ba2str(&(info+i)->bdaddr, addr); - printf("\t%s\t%s\n", addr, name); + printf("Device name:\t%s\n", name); + + if (extcls) { + memcpy(cls, (info+i)->dev_class, 3); + printf("Device class:\t"); + if ((cls[1] & 0x1f) > sizeof(*major_classes)) + printf("Invalid"); + else + printf("%s, %s", major_classes[cls[1] & 0x1f], + get_minor_device_name(cls[1] & 0x1f, cls[0] >> 2)); + printf(" (0x%2.2x%2.2x%2.2x)\n", cls[2], cls[1], cls[0]); + } + + if (extinf && handle > 0) { + if (hci_read_remote_version(dd, handle, &version, 20000) == 0) { + printf("Manufacturer:\t%s (%d)\n", + bt_compidtostr(version.manufacturer), + version.manufacturer); + printf("LMP version:\t%s (0x%x) [subver 0x%x]\n", + lmp_vertostr(version.lmp_ver), + version.lmp_ver, version.lmp_subver); + } + + if (hci_read_remote_features(dd, handle, features, 20000) == 0) { + printf("LMP features:\t0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x" + " 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", + features[0], features[1], + features[2], features[3], + features[4], features[5], + features[6], features[7]); + printf("%s\n", lmp_featurestostr(features, "\t\t", 63)); + } + + if (cc) { + usleep(10000); + hci_disconnect(dd, handle, HCI_OE_USER_ENDED_CONNECTION, 10000); + } + } + + printf("\n"); } close(dd); @@ -491,302 +754,6 @@ static void cmd_info(int dev_id, int argc, char **argv) close(dd); } -/* Find remote devices */ - -static struct option find_options[] = { - { "help", 0, 0, 'h' }, - { "length", 1, 0, 'l' }, - { "numrsp", 1, 0, 'n' }, - { "flush", 0, 0, 'f' }, - { 0, 0, 0, 0 } -}; - -static char *find_help = - "Usage:\n" - "\tfind [--length=N] [--numrsp=N] [--flush]\n"; - -static char *get_minor_device_name(int major, int minor) -{ - switch (major) { - case 0: /* misc */ - return ""; - case 1: /* computer */ - switch(minor) { - case 0: - return "Uncategorized"; - case 1: - return "Desktop workstation"; - case 2: - return "Server"; - case 3: - return "Laptop"; - case 4: - return "Handheld"; - case 5: - return "Palm"; - case 6: - return "Wearable"; - } - break; - case 2: /* phone */ - switch(minor) { - case 0: - return "Uncategorized"; - case 1: - return "Cellular"; - case 2: - return "Cordless"; - case 3: - return "Smart phone"; - case 4: - return "Wired modem or voice gateway"; - case 5: - return "Common ISDN Access"; - case 6: - return "Sim Card Reader"; - } - break; - case 3: /* lan access */ - if (minor == 0) - return "Uncategorized"; - switch(minor / 8) { - case 0: - return "Fully available"; - case 1: - return "1-17% utilized"; - case 2: - return "17-33% utilized"; - case 3: - return "33-50% utilized"; - case 4: - return "50-67% utilized"; - case 5: - return "67-83% utilized"; - case 6: - return "83-99% utilized"; - case 7: - return "No service available"; - } - break; - case 4: /* audio/video */ - switch(minor) { - case 0: - return "Uncategorized"; - case 1: - return "Device conforms to the Headset profile"; - case 2: - return "Hands-free"; - /* 3 is reserved */ - case 4: - return "Microphone"; - case 5: - return "Loudspeaker"; - case 6: - return "Headphones"; - case 7: - return "Portable Audio"; - case 8: - return "Car Audio"; - case 9: - return "Set-top box"; - case 10: - return "HiFi Audio Device"; - case 11: - return "VCR"; - case 12: - return "Video Camera"; - case 13: - return "Camcorder"; - case 14: - return "Video Monitor"; - case 15: - return "Video Display and Loudspeaker"; - case 16: - return "Video Conferencing"; - /* 17 is reserved */ - case 18: - return "Gaming/Toy"; - } - break; - case 5: /* peripheral */ - switch(minor) { - case 16: - return "Keyboard"; - case 32: - return "Pointing device"; - case 48: - return "Combo keyboard/pointing device"; - } - break; - case 6: /* imaging */ - if (minor & 4) - return "Display"; - if (minor & 8) - return "Camera"; - if (minor & 16) - return "Scanner"; - if (minor & 32) - return "Printer"; - break; - case 63: /* uncategorised */ - return ""; - } - return "Unknown (reserved) minor device class"; -} - -static char *major_classes[] = { - "Miscellaneous", "Computer", "Phone", "LAN Access", - "Audio/Video", "Peripheral", "Imaging", "Uncategorized" -}; - -static void cmd_find(int dev_id, int argc, char **argv) -{ - inquiry_info *info = NULL; - int num_rsp, length, flags; - uint8_t cls[3]; - uint16_t handle; - char addr[18], name[249], oui[9], *comp; - unsigned char features[8]; - struct hci_version version; - struct hci_dev_info di; - struct hci_conn_info_req *cr; - int i, opt, dd, cc = 0; - - length = 8; /* ~10 seconds */ - num_rsp = 100; - flags = 0; - - for_each_opt(opt, find_options, NULL) { - switch (opt) { - case 'l': - length = atoi(optarg); - break; - - case 'n': - num_rsp = atoi(optarg); - break; - - case 'f': - flags |= IREQ_CACHE_FLUSH; - break; - - default: - printf(find_help); - return; - } - } - - if (dev_id < 0) { - dev_id = hci_get_route(NULL); - if (dev_id < 0) { - perror("Device is not available"); - exit(1); - } - } - - if (hci_devinfo(dev_id, &di) < 0) { - perror("Can't get device info"); - exit(1); - } - - printf("Searching ...\n"); - num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); - if (num_rsp < 0) { - perror("Inquiry failed"); - exit(1); - } - - dd = hci_open_dev(dev_id); - if (dd < 0) { - perror("HCI device open failed"); - free(info); - exit(1); - } - - printf("\n"); - - for (i = 0; i < num_rsp; i++) { - ba2str(&(info+i)->bdaddr, addr); - printf("BD Address:\t%s [mode %d, clkoffset 0x%4.4x]\n", addr, - (info+i)->pscan_rep_mode, btohs((info+i)->clock_offset)); - - ba2oui(&(info+i)->bdaddr, oui); - comp = ouitocomp(oui); - if (comp) { - printf("OUI company:\t%s (%s)\n", comp, oui); - free(comp); - } - - cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (cr) { - bacpy(&cr->bdaddr, &(info+i)->bdaddr); - cr->type = ACL_LINK; - if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { - if (hci_create_connection(dd, &(info+i)->bdaddr, - htobs(di.pkt_type & ACL_PTYPE_MASK), - (info+i)->clock_offset | 0x8000, - 0x01, &handle, 25000) < 0) - handle = 0; - else - cc = 1; - } else - handle = htobs(cr->conn_info->handle); - } else - handle = 0; - - memset(name, 0, sizeof(name)); - if (hci_read_remote_name_with_clock_offset(dd, &(info+i)->bdaddr, - (info+i)->pscan_rep_mode, - (info+i)->clock_offset | 0x8000, - sizeof(name), name, 100000) < 0) - strcpy(name, "n/a"); - printf("Device name:\t%s\n", name); - - memcpy(cls, (info+i)->dev_class, 3); - printf("Device class:\t"); - if ((cls[1] & 0x1f) > sizeof(*major_classes)) - printf("Invalid"); - else - printf("%s, %s", major_classes[cls[1] & 0x1f], - get_minor_device_name(cls[1] & 0x1f, cls[0] >> 2)); - printf(" (0x%2.2x%2.2x%2.2x)\n", cls[2], cls[1], cls[0]); - - if (handle > 0) { - if (hci_read_remote_version(dd, handle, &version, 20000) == 0) { - printf("Manufacturer:\t%s (%d)\n", - bt_compidtostr(version.manufacturer), - version.manufacturer); - printf("LMP version:\t%s (0x%x) [subver 0x%x]\n", - lmp_vertostr(version.lmp_ver), - version.lmp_ver, version.lmp_subver); - } - - if (hci_read_remote_features(dd, handle, features, 20000) == 0) { - printf("LMP features:\t0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x" - " 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", - features[0], features[1], - features[2], features[3], - features[4], features[5], - features[6], features[7]); - printf("%s\n", lmp_featurestostr(features, "\t\t", 63)); - } - - if (cc) { - usleep(10000); - hci_disconnect(dd, handle, HCI_OE_USER_ENDED_CONNECTION, 10000); - } - } - - printf("\n"); - - if (cr) - free(cr); - } - - close(dd); - free(info); -} - /* Send arbitrary HCI commands */ static struct option cmd_options[] = { @@ -1942,7 +1909,6 @@ static struct { { "scan", cmd_scan, "Scan for remote devices" }, { "name", cmd_name, "Get name from remote device" }, { "info", cmd_info, "Get information from remote device" }, - { "find", cmd_find, "Search for remote devices" }, { "cmd", cmd_cmd, "Submit arbitrary HCI commands" }, { "con", cmd_con, "Display active connections" }, { "cc", cmd_cc, "Create connection to remote device" }, -- cgit From 304b8bb466c0b015d30f9dfbc785d2a7c0a2ef79 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 16 Apr 2005 22:46:13 +0000 Subject: Make use of the device name cache --- tools/hcitool.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 82 insertions(+), 9 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 9ac890fd..947da44e 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -34,9 +34,12 @@ #include #include +#include #include #include #include +#include +#include #include #include @@ -276,6 +279,63 @@ static char *major_classes[] = { "Audio/Video", "Peripheral", "Imaging", "Uncategorized" }; +#define DEVPATH "/var/lib/bluetooth/" + +static int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *name) +{ + char filename[PATH_MAX + 1], addr[18], str[249], *buf, *ptr; + bdaddr_t bdaddr; + struct stat st; + int fd, pos, err = 0; + + ba2str(local, addr); + snprintf(filename, PATH_MAX, "%s/%s/names", DEVPATH, addr); + + fd = open(filename, O_RDONLY); + if (fd < 0) + return -errno; + + if (flock(fd, LOCK_SH) < 0) { + err = -errno; + goto close; + } + + if (fstat(fd, &st) < 0) { + err = -errno; + goto unlock; + } + + buf = malloc(st.st_size); + if (!buf) { + err = -ENOMEM; + goto unlock; + } + + if (st.st_size > 0) { + read(fd, buf, st.st_size); + + ptr = buf; + + while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { + str2ba(addr, &bdaddr); + + if (!bacmp(&bdaddr, peer)) { + snprintf(name, 249, "%s", str); + break; + } + + ptr += pos; + }; + } + +unlock: + flock(fd, LOCK_UN); + +close: + close(fd); + return err; +} + /* Display local devices */ static struct option dev_options[] = { @@ -398,7 +458,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) struct hci_dev_info di; struct hci_conn_info_req *cr; int extcls = 0, extinf = 0, extoui = 0; - int i, opt, dd, cc; + int i, opt, dd, cc, nc; length = 8; /* ~10 seconds */ num_rsp = 100; @@ -473,7 +533,17 @@ static void cmd_scan(int dev_id, int argc, char **argv) printf("\n"); for (i = 0; i < num_rsp; i++) { + memset(name, 0, sizeof(name)); + nc = read_device_name(&di.bdaddr, &(info+i)->bdaddr, name) < 0 ? 0 : 1; + if (!extcls && !extinf && !extoui) { + ba2str(&(info+i)->bdaddr, addr); + + if (nc) { + printf("\t%s\t%s\n", addr, name); + continue; + } + memset(name, 0, sizeof(name)); if (hci_read_remote_name_with_clock_offset(dd, &(info+i)->bdaddr, @@ -481,7 +551,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) (info+i)->clock_offset | 0x8000, sizeof(name), name, 100000) < 0) strcpy(name, "n/a"); - ba2str(&(info+i)->bdaddr, addr); + printf("\t%s\t%s\n", addr, name); continue; } @@ -527,13 +597,16 @@ static void cmd_scan(int dev_id, int argc, char **argv) } } - memset(name, 0, sizeof(name)); - if (hci_read_remote_name_with_clock_offset(dd, &(info+i)->bdaddr, - (info+i)->pscan_rep_mode, - (info+i)->clock_offset | 0x8000, - sizeof(name), name, 100000) < 0) - strcpy(name, "n/a"); - printf("Device name:\t%s\n", name); + if (handle > 0 || !nc) { + memset(name, 0, sizeof(name)); + if (hci_read_remote_name_with_clock_offset(dd, + &(info+i)->bdaddr, + (info+i)->pscan_rep_mode, + (info+i)->clock_offset | 0x8000, + sizeof(name), name, 100000) < 0) + strcpy(name, "n/a"); + } + printf("Device name:\t%s%s\n", name, nc ? " [cached]" : ""); if (extcls) { memcpy(cls, (info+i)->dev_class, 3); -- cgit From 91ec71874613cf65ab0abdaaf62c0b4e6a56a40e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 16 Apr 2005 22:52:36 +0000 Subject: Fix the name cache state --- tools/hcitool.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 947da44e..a17fe8bc 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -544,7 +544,6 @@ static void cmd_scan(int dev_id, int argc, char **argv) continue; } - memset(name, 0, sizeof(name)); if (hci_read_remote_name_with_clock_offset(dd, &(info+i)->bdaddr, (info+i)->pscan_rep_mode, @@ -598,13 +597,15 @@ static void cmd_scan(int dev_id, int argc, char **argv) } if (handle > 0 || !nc) { - memset(name, 0, sizeof(name)); if (hci_read_remote_name_with_clock_offset(dd, &(info+i)->bdaddr, (info+i)->pscan_rep_mode, (info+i)->clock_offset | 0x8000, - sizeof(name), name, 100000) < 0) - strcpy(name, "n/a"); + sizeof(name), name, 100000) < 0) { + if (!nc) + strcpy(name, "n/a"); + } else + nc = 0; } printf("Device name:\t%s%s\n", name, nc ? " [cached]" : ""); -- cgit From 12513fafd320f210190ab574383efe9591ce6c6e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 16 Apr 2005 22:58:53 +0000 Subject: Fix the case if device isn't found in the name cache --- tools/hcitool.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index a17fe8bc..5106f664 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -286,7 +286,7 @@ static int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *n char filename[PATH_MAX + 1], addr[18], str[249], *buf, *ptr; bdaddr_t bdaddr; struct stat st; - int fd, pos, err = 0; + int fd, pos, err = -ENOENT; ba2str(local, addr); snprintf(filename, PATH_MAX, "%s/%s/names", DEVPATH, addr); @@ -321,6 +321,7 @@ static int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *n if (!bacmp(&bdaddr, peer)) { snprintf(name, 249, "%s", str); + err = 0; break; } @@ -534,7 +535,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) for (i = 0; i < num_rsp; i++) { memset(name, 0, sizeof(name)); - nc = read_device_name(&di.bdaddr, &(info+i)->bdaddr, name) < 0 ? 0 : 1; + nc = (read_device_name(&di.bdaddr, &(info+i)->bdaddr, name) == 0); if (!extcls && !extinf && !extoui) { ba2str(&(info+i)->bdaddr, addr); -- cgit From 24793e9a7eb16ed4f749b32419154bc2a58bbc1d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 17 Apr 2005 01:05:27 +0000 Subject: Improve reading device names from cache --- tools/hcitool.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 5106f664..6da3d3c1 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -316,8 +316,10 @@ static int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *n ptr = buf; + memset(str, 0, sizeof(str)); while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { str2ba(addr, &bdaddr); + str[sizeof(str) - 1] = '\0'; if (!bacmp(&bdaddr, peer)) { snprintf(name, 249, "%s", str); @@ -325,7 +327,10 @@ static int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *n break; } + memset(str, 0, sizeof(str)); ptr += pos; + if (ptr - buf >= st.st_size) + break; }; } -- cgit From c3881e06e2262909d8e1c190622002c5e02d724f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 17 Apr 2005 23:34:20 +0000 Subject: Check the number of pages for extended features --- tools/hcitool.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 6da3d3c1..e02cb93f 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -456,10 +456,9 @@ static void cmd_scan(int dev_id, int argc, char **argv) { inquiry_info *info = NULL; int num_rsp, length, flags; - uint8_t cls[3]; + uint8_t cls[3], features[8]; uint16_t handle; char addr[18], name[249], oui[9], *comp; - unsigned char features[8]; struct hci_version version; struct hci_dev_info di; struct hci_conn_info_req *cr; @@ -728,8 +727,8 @@ static void cmd_info(int dev_id, int argc, char **argv) { bdaddr_t bdaddr; uint16_t handle; + uint8_t max_page, features[8]; char name[249], oui[9], *comp; - unsigned char features[8]; struct hci_version version; struct hci_dev_info di; struct hci_conn_info_req *cr; @@ -826,6 +825,12 @@ static void cmd_info(int dev_id, int argc, char **argv) lmp_featurestostr(features, "\t\t", 63)); } + if (features[7] & 0x80) { + if (hci_read_remote_ext_features(dd, handle, 0, &max_page, features, 20000) == 0) + if (max_page > 0) + printf("\tExtended features: %d pages\n", max_page); + } + if (cc) { usleep(10000); hci_disconnect(dd, handle, HCI_OE_USER_ENDED_CONNECTION, 10000); -- cgit From bb30c261fcdb833bf5cac02f671822bbe443ff27 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 18 Apr 2005 21:09:59 +0000 Subject: Use LMP_EXT_FEAT constant --- tools/hcitool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index e02cb93f..0b35b1ac 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -825,7 +825,7 @@ static void cmd_info(int dev_id, int argc, char **argv) lmp_featurestostr(features, "\t\t", 63)); } - if (features[7] & 0x80) { + if (features[7] & LMP_EXT_FEAT) { if (hci_read_remote_ext_features(dd, handle, 0, &max_page, features, 20000) == 0) if (max_page > 0) printf("\tExtended features: %d pages\n", max_page); -- cgit From be0264a76e5658b41a23ed7a9228eb27490abf58 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 18 Apr 2005 22:23:55 +0000 Subject: Use unlimited inquiry responses as default --- tools/hcitool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 0b35b1ac..453ef2e3 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -392,7 +392,7 @@ static void cmd_inq(int dev_id, int argc, char **argv) int i, opt; length = 8; /* ~10 seconds */ - num_rsp = 100; + num_rsp = 0; flags = 0; for_each_opt(opt, inq_options, NULL) { @@ -466,7 +466,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) int i, opt, dd, cc, nc; length = 8; /* ~10 seconds */ - num_rsp = 100; + num_rsp = 0; flags = 0; for_each_opt(opt, scan_options, NULL) { -- cgit From f5a214f76f2d93702b5bc3b0b168389d8f8b34f2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 21 Apr 2005 20:18:09 +0000 Subject: Set the storage directory through ${localstatedir} --- tools/hcitool.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 453ef2e3..fb189760 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -279,8 +279,6 @@ static char *major_classes[] = { "Audio/Video", "Peripheral", "Imaging", "Uncategorized" }; -#define DEVPATH "/var/lib/bluetooth/" - static int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *name) { char filename[PATH_MAX + 1], addr[18], str[249], *buf, *ptr; @@ -289,7 +287,7 @@ static int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *n int fd, pos, err = -ENOENT; ba2str(local, addr); - snprintf(filename, PATH_MAX, "%s/%s/names", DEVPATH, addr); + snprintf(filename, PATH_MAX, "%s/%s/names", STORAGEDIR, addr); fd = open(filename, O_RDONLY); if (fd < 0) -- cgit From 70e5fac9bd0fb2294eb7e585c005eb096ae84f5d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 22 Apr 2005 11:52:29 +0000 Subject: Include sys/param.h for PATH_MAX --- tools/hcitool.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index fb189760..a30e7098 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include -- cgit From cb079810a52ebbc4ec46c33b2a0f31a6b9c8c778 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 22 Apr 2005 12:18:52 +0000 Subject: Use the new textfile library --- tools/hcitool.c | 71 +++++++++++---------------------------------------------- 1 file changed, 13 insertions(+), 58 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index a30e7098..6e225cee 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -38,8 +38,6 @@ #include #include #include -#include -#include #include #include #include @@ -48,6 +46,7 @@ #include #include +#include "textfile.h" #include "oui.h" #define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, NULL)) != -1) @@ -280,65 +279,15 @@ static char *major_classes[] = { "Audio/Video", "Peripheral", "Imaging", "Uncategorized" }; -static int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *name) +static char *get_device_name(const bdaddr_t *local, const bdaddr_t *peer) { - char filename[PATH_MAX + 1], addr[18], str[249], *buf, *ptr; - bdaddr_t bdaddr; - struct stat st; - int fd, pos, err = -ENOENT; + char filename[PATH_MAX + 1], addr[18]; ba2str(local, addr); snprintf(filename, PATH_MAX, "%s/%s/names", STORAGEDIR, addr); - fd = open(filename, O_RDONLY); - if (fd < 0) - return -errno; - - if (flock(fd, LOCK_SH) < 0) { - err = -errno; - goto close; - } - - if (fstat(fd, &st) < 0) { - err = -errno; - goto unlock; - } - - buf = malloc(st.st_size); - if (!buf) { - err = -ENOMEM; - goto unlock; - } - - if (st.st_size > 0) { - read(fd, buf, st.st_size); - - ptr = buf; - - memset(str, 0, sizeof(str)); - while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { - str2ba(addr, &bdaddr); - str[sizeof(str) - 1] = '\0'; - - if (!bacmp(&bdaddr, peer)) { - snprintf(name, 249, "%s", str); - err = 0; - break; - } - - memset(str, 0, sizeof(str)); - ptr += pos; - if (ptr - buf >= st.st_size) - break; - }; - } - -unlock: - flock(fd, LOCK_UN); - -close: - close(fd); - return err; + ba2str(peer, addr); + return textfile_get(filename, addr); } /* Display local devices */ @@ -457,7 +406,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) int num_rsp, length, flags; uint8_t cls[3], features[8]; uint16_t handle; - char addr[18], name[249], oui[9], *comp; + char addr[18], name[249], oui[9], *comp, *tmp; struct hci_version version; struct hci_dev_info di; struct hci_conn_info_req *cr; @@ -538,7 +487,13 @@ static void cmd_scan(int dev_id, int argc, char **argv) for (i = 0; i < num_rsp; i++) { memset(name, 0, sizeof(name)); - nc = (read_device_name(&di.bdaddr, &(info+i)->bdaddr, name) == 0); + tmp = get_device_name(&di.bdaddr, &(info+i)->bdaddr); + if (tmp) { + strncpy(name, tmp, 249); + free(tmp); + nc = 1; + } else + nc = 0; if (!extcls && !extinf && !extoui) { ba2str(&(info+i)->bdaddr, addr); -- cgit From 3257d9b3a8f59561960c75f310fea33d23858024 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 16 Jun 2005 21:25:49 +0000 Subject: Fix program error codes on memory allocations --- tools/hcitool.c | 72 ++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 24 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 6e225cee..210ab2ba 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1030,8 +1030,10 @@ static void cmd_dc(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1165,8 +1167,10 @@ static void cmd_rssi(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1236,8 +1240,10 @@ static void cmd_lq(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1309,8 +1315,10 @@ static void cmd_tpl(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1382,8 +1390,10 @@ static void cmd_afh(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1465,8 +1475,10 @@ static void cmd_cpt(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1546,8 +1558,10 @@ static void cmd_lst(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1631,8 +1645,10 @@ static void cmd_auth(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1700,8 +1716,10 @@ static void cmd_enc(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1770,8 +1788,10 @@ static void cmd_key(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1839,8 +1859,10 @@ static void cmd_clkoff(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1912,8 +1934,10 @@ static void cmd_clock(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; -- cgit From 1d2e71b109d907473939864caa5afec86000d58a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 17 Jun 2005 12:10:54 +0000 Subject: Replace non-printable characters in device names --- tools/hcitool.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 210ab2ba..e6561feb 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -411,7 +412,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) struct hci_dev_info di; struct hci_conn_info_req *cr; int extcls = 0, extinf = 0, extoui = 0; - int i, opt, dd, cc, nc; + int i, n, opt, dd, cc, nc; length = 8; /* ~10 seconds */ num_rsp = 0; @@ -510,6 +511,10 @@ static void cmd_scan(int dev_id, int argc, char **argv) sizeof(name), name, 100000) < 0) strcpy(name, "n/a"); + for (n = 0; n < 248 && name[n]; n++) + if (!isprint(name[n])) + name[n] = '.'; + printf("\t%s\t%s\n", addr, name); continue; } @@ -563,8 +568,12 @@ static void cmd_scan(int dev_id, int argc, char **argv) sizeof(name), name, 100000) < 0) { if (!nc) strcpy(name, "n/a"); - } else + } else { + for (n = 0; n < 248 && name[n]; n++) + if (!isprint(name[n])) + name[n] = '.'; nc = 0; + } } printf("Device name:\t%s%s\n", name, nc ? " [cached]" : ""); -- cgit From a32c06bc2990f56420782e8966aa5de08b61d505 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 3 Jul 2005 10:08:26 +0000 Subject: Update reading of local Bluetooth clock --- tools/hcitool.c | 51 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 21 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index e6561feb..7f0cc23a 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1900,14 +1900,14 @@ static struct option clock_options[] = { static char *clock_help = "Usage:\n" - "\tclock [which clock]\n"; + "\tclock [bdaddr] [which clock]\n"; static void cmd_clock(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; bdaddr_t bdaddr; uint8_t which; - uint32_t clock; + uint32_t handle, clock; uint16_t accuracy; int opt, dd; @@ -1921,12 +1921,13 @@ static void cmd_clock(int dev_id, int argc, char **argv) argc -= optind; argv += optind; - if (argc < 1) { - printf(clock_help); - return; - } + if (argc > 0) + str2ba(argv[0], &bdaddr); + else + bacpy(&bdaddr, BDADDR_ANY); - str2ba(argv[0], &bdaddr); + if (!bacmp(&bdaddr, BDADDR_ANY)) + dev_id = hci_get_route(NULL); if (dev_id < 0) { dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); @@ -1942,22 +1943,31 @@ static void cmd_clock(int dev_id, int argc, char **argv) exit(1); } - cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) { - perror("Can't allocate memory"); - exit(1); - } + if (bacmp(&bdaddr, BDADDR_ANY)) { + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } - bacpy(&cr->bdaddr, &bdaddr); - cr->type = ACL_LINK; - if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { - perror("Get connection info failed"); - exit(1); - } + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + free(cr); + exit(1); + } + + handle = htobs(cr->conn_info->handle); + which = (argc > 1) ? atoi(argv[1]) : 0x01; - which = (argc > 1) ? atoi(argv[1]) : 0x01; + free(cr); + } else { + handle = 0x00; + which = 0x00; + } - if (hci_read_clock(dd, htobs(cr->conn_info->handle), which, &clock, &accuracy, 1000) < 0) { + if (hci_read_clock(dd, handle, which, &clock, &accuracy, 1000) < 0) { perror("Reading clock failed"); exit(1); } @@ -1968,7 +1978,6 @@ static void cmd_clock(int dev_id, int argc, char **argv) printf("Accuracy: %.2f msec\n", (float) accuracy * 0.3125); close(dd); - free(cr); } static struct { -- cgit From cbbe4f3f909cde4356f1323e0bd157e2fe9320de Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 3 Jul 2005 13:01:52 +0000 Subject: Don't show empty names --- tools/hcitool.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 7f0cc23a..ceddeda5 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -575,7 +575,9 @@ static void cmd_scan(int dev_id, int argc, char **argv) nc = 0; } } - printf("Device name:\t%s%s\n", name, nc ? " [cached]" : ""); + + if (strlen(name) > 0) + printf("Device name:\t%s%s\n", name, nc ? " [cached]" : ""); if (extcls) { memcpy(cls, (info+i)->dev_class, 3); -- cgit From 1f422e5f2b343d35a8c77ce4be16f74b2819b2bf Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 5 Jul 2005 21:15:41 +0000 Subject: Fix some GCC 4.0 warnings --- tools/hcitool.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index ceddeda5..156b0790 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -819,7 +819,7 @@ static char *cmd_help = static void cmd_cmd(int dev_id, int argc, char **argv) { - char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; + unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; struct hci_filter flt; hci_event_hdr *hdr; int i, opt, len, dd; @@ -940,9 +940,10 @@ static char *cc_help = static void cmd_cc(int dev_id, int argc, char **argv) { bdaddr_t bdaddr; - int opt, ptype, dd; uint16_t handle; uint8_t role; + unsigned int ptype; + int dd, opt; role = 0x01; ptype = HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5; @@ -1451,7 +1452,8 @@ static void cmd_cpt(int dev_id, int argc, char **argv) set_conn_ptype_cp cp; evt_conn_ptype_changed rp; bdaddr_t bdaddr; - int opt, dd, ptype; + unsigned int ptype; + int dd, opt; for_each_opt(opt, cpt_options, NULL) { switch (opt) { -- cgit From 8ac83f1424fe8c726aeeccda705c6840d5b31ab9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 5 Aug 2005 03:24:28 +0000 Subject: Correctly terminate the device name string --- tools/hcitool.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 156b0790..ba8ba823 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -514,6 +514,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) for (n = 0; n < 248 && name[n]; n++) if (!isprint(name[n])) name[n] = '.'; + name[248] = '\0'; printf("\t%s\t%s\n", addr, name); continue; @@ -572,6 +573,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) for (n = 0; n < 248 && name[n]; n++) if (!isprint(name[n])) name[n] = '.'; + name[248] = '\0'; nc = 0; } } -- cgit From ad3049f07e580ee1ffb235afea1e368c4c46a639 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 5 Aug 2005 07:34:55 +0000 Subject: Use bt_free() to free the memory allocated by lmp_featurestostr() --- tools/hcitool.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index ba8ba823..bc09ea07 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -379,7 +379,8 @@ static void cmd_inq(int dev_id, int argc, char **argv) (info+i)->dev_class[1], (info+i)->dev_class[0]); } - free(info); + + bt_free(info); } /* Device scanning */ @@ -603,13 +604,15 @@ static void cmd_scan(int dev_id, int argc, char **argv) } if (hci_read_remote_features(dd, handle, features, 20000) == 0) { + char *tmp = lmp_featurestostr(features, "\t\t", 63); printf("LMP features:\t0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x" " 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", features[0], features[1], features[2], features[3], features[4], features[5], features[6], features[7]); - printf("%s\n", lmp_featurestostr(features, "\t\t", 63)); + printf("%s\n", tmp); + bt_free(tmp); } if (cc) { @@ -622,7 +625,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) } close(dd); - free(info); + bt_free(info); } /* Remote name */ @@ -786,10 +789,11 @@ static void cmd_info(int dev_id, int argc, char **argv) } if (hci_read_remote_features(dd, handle, features, 20000) == 0) { + char *tmp = lmp_featurestostr(features, "\t\t", 63); printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n%s\n", features[0], features[1], features[2], features[3], - features[4], features[5], features[6], features[7], - lmp_featurestostr(features, "\t\t", 63)); + features[4], features[5], features[6], features[7], tmp); + bt_free(tmp); } if (features[7] & LMP_EXT_FEAT) { -- cgit From 9848c1fa4ee7b49d425cb790fe9ab5edff8761dd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 7 Sep 2005 16:15:39 +0000 Subject: Show supported commands also in clear text --- tools/hcitool.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index bc09ea07..2865ec42 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -595,12 +595,15 @@ static void cmd_scan(int dev_id, int argc, char **argv) if (extinf && handle > 0) { if (hci_read_remote_version(dd, handle, &version, 20000) == 0) { + char *ver = lmp_vertostr(version.lmp_ver); printf("Manufacturer:\t%s (%d)\n", bt_compidtostr(version.manufacturer), version.manufacturer); printf("LMP version:\t%s (0x%x) [subver 0x%x]\n", - lmp_vertostr(version.lmp_ver), + ver ? ver : "n/a", version.lmp_ver, version.lmp_subver); + if (ver) + bt_free(ver); } if (hci_read_remote_features(dd, handle, features, 20000) == 0) { @@ -779,13 +782,16 @@ static void cmd_info(int dev_id, int argc, char **argv) printf("\tDevice Name: %s\n", name); if (hci_read_remote_version(dd, handle, &version, 20000) == 0) { + char *ver = lmp_vertostr(version.lmp_ver); printf("\tLMP Version: %s (0x%x) LMP Subversion: 0x%x\n" "\tManufacturer: %s (%d)\n", - lmp_vertostr(version.lmp_ver), + ver ? ver : "n/a", version.lmp_ver, version.lmp_subver, bt_compidtostr(version.manufacturer), version.manufacturer); + if (ver) + bt_free(ver); } if (hci_read_remote_features(dd, handle, features, 20000) == 0) { -- cgit From bf1758786cd88dbf3ae3d113f7fce95c43ee71eb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 29 Sep 2005 11:13:25 +0000 Subject: Add support for inquiry access codes --- tools/hcitool.c | 57 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 15 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 2865ec42..1804d9fd 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -323,6 +323,7 @@ static struct option inq_options[] = { { "help", 0, 0, 'h' }, { "length", 1, 0, 'l' }, { "numrsp", 1, 0, 'n' }, + { "iac", 1, 0, 'i' }, { "flush", 0, 0, 'f' }, { 0, 0, 0, 0 } }; @@ -331,14 +332,16 @@ static char *inq_help = "Usage:\n" "\tinq [--length=N] maximum inquiry duration in 1.28 s units\n" "\t [--numrsp=N] specify maximum number of inquiry responses\n" + "\t [--iac=lap] specify the inquiry access code\n" "\t [--flush] flush the inquiry cache\n"; static void cmd_inq(int dev_id, int argc, char **argv) { - int num_rsp, length, flags; inquiry_info *info = NULL; + uint8_t lap[3] = { 0x33, 0x8b, 0x9e }; + int num_rsp, length, flags; char addr[18]; - int i, opt; + int i, l, opt; length = 8; /* ~10 seconds */ num_rsp = 0; @@ -354,6 +357,17 @@ static void cmd_inq(int dev_id, int argc, char **argv) num_rsp = atoi(optarg); break; + case 'i': + l = strtoul(optarg, 0, 16); + if (l < 0x9e8b00 || l > 0x9e8b3f) { + printf("Invalid access code 0x%x\n", l); + exit(1); + } + lap[0] = (l & 0xff); + lap[1] = (l >> 8) & 0xff; + lap[2] = (l >> 16) & 0xff; + break; + case 'f': flags |= IREQ_CACHE_FLUSH; break; @@ -365,7 +379,7 @@ static void cmd_inq(int dev_id, int argc, char **argv) } printf("Inquiring ...\n"); - num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); + num_rsp = hci_inquiry(dev_id, length, num_rsp, lap, &info, flags); if (num_rsp < 0) { perror("Inquiry failed."); exit(1); @@ -389,22 +403,24 @@ static struct option scan_options[] = { { "help", 0, 0, 'h' }, { "length", 1, 0, 'l' }, { "numrsp", 1, 0, 'n' }, + { "iac", 1, 0, 'i' }, { "flush", 0, 0, 'f' }, - { "class", 0, 0, 'c' }, - { "info", 0, 0, 'i' }, - { "oui", 0, 0, 'o' }, - { "all", 0, 0, 'a' }, - { "ext", 0, 0, 'a' }, + { "class", 0, 0, 'C' }, + { "info", 0, 0, 'I' }, + { "oui", 0, 0, 'O' }, + { "all", 0, 0, 'A' }, + { "ext", 0, 0, 'A' }, { 0, 0, 0, 0 } }; static char *scan_help = "Usage:\n" - "\tscan [--length=N] [--numrsp=N] [--flush] [--class] [--info] [--oui]\n"; + "\tscan [--length=N] [--numrsp=N] [--iac=lap] [--flush] [--class] [--info] [--oui]\n"; static void cmd_scan(int dev_id, int argc, char **argv) { inquiry_info *info = NULL; + uint8_t lap[3] = { 0x33, 0x8b, 0x9e }; int num_rsp, length, flags; uint8_t cls[3], features[8]; uint16_t handle; @@ -413,7 +429,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) struct hci_dev_info di; struct hci_conn_info_req *cr; int extcls = 0, extinf = 0, extoui = 0; - int i, n, opt, dd, cc, nc; + int i, n, l, opt, dd, cc, nc; length = 8; /* ~10 seconds */ num_rsp = 0; @@ -429,23 +445,34 @@ static void cmd_scan(int dev_id, int argc, char **argv) num_rsp = atoi(optarg); break; + case 'i': + l = strtoul(optarg, 0, 16); + if (l < 0x9e8b00 || l > 0x9e8b3f) { + printf("Invalid access code 0x%x\n", l); + exit(1); + } + lap[0] = (l & 0xff); + lap[1] = (l >> 8) & 0xff; + lap[2] = (l >> 16) & 0xff; + break; + case 'f': flags |= IREQ_CACHE_FLUSH; break; - case 'c': + case 'C': extcls = 1; break; - case 'i': + case 'I': extinf = 1; break; - case 'o': + case 'O': extoui = 1; break; - case 'a': + case 'A': extcls = 1; extinf = 1; extoui = 1; @@ -471,7 +498,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) } printf("Scanning ...\n"); - num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); + num_rsp = hci_inquiry(dev_id, length, num_rsp, lap, &info, flags); if (num_rsp < 0) { perror("Inquiry failed"); exit(1); -- cgit From 97a6bcbbe32c89438f4f54e47b376c75e2949763 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 21 Oct 2005 11:44:26 +0000 Subject: Allow clear text IAC values --- tools/hcitool.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 1804d9fd..75b09b77 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -359,7 +360,11 @@ static void cmd_inq(int dev_id, int argc, char **argv) case 'i': l = strtoul(optarg, 0, 16); - if (l < 0x9e8b00 || l > 0x9e8b3f) { + if (!strcasecmp(optarg, "giac")) { + l = 0x9e8b33; + } else if (!strcasecmp(optarg, "liac")) { + l = 0x9e8b00; + } if (l < 0x9e8b00 || l > 0x9e8b3f) { printf("Invalid access code 0x%x\n", l); exit(1); } @@ -447,7 +452,11 @@ static void cmd_scan(int dev_id, int argc, char **argv) case 'i': l = strtoul(optarg, 0, 16); - if (l < 0x9e8b00 || l > 0x9e8b3f) { + if (!strcasecmp(optarg, "giac")) { + l = 0x9e8b33; + } else if (!strcasecmp(optarg, "liac")) { + l = 0x9e8b00; + } else if (l < 0x9e8b00 || l > 0x9e8b3f) { printf("Invalid access code 0x%x\n", l); exit(1); } -- cgit From 632a9432774ff3a0c6e556e8f32a565b38890767 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 29 Oct 2005 22:36:31 +0000 Subject: Big cleanup of CVS relics --- tools/hcitool.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 75b09b77..9ae42a12 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -8,24 +8,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 * - * - * $Id$ */ #ifdef HAVE_CONFIG_H -- cgit From f2e48c44a7e4c9ee31b8ce2e302186f6047cfeab Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 3 Jan 2006 13:28:56 +0000 Subject: Update copyright information --- tools/hcitool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 9ae42a12..85404afc 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify -- cgit From da7aed3f3f9377f68a7aebe645ef4e8b1f6f1d92 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 18 Jan 2006 17:45:51 +0000 Subject: Use the correct device for reading the local clock --- tools/hcitool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 85404afc..2ad26bfe 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1973,7 +1973,7 @@ static void cmd_clock(int dev_id, int argc, char **argv) else bacpy(&bdaddr, BDADDR_ANY); - if (!bacmp(&bdaddr, BDADDR_ANY)) + if (dev_id < 0 && !bacmp(&bdaddr, BDADDR_ANY)) dev_id = hci_get_route(NULL); if (dev_id < 0) { -- cgit From 403066f6cd6f4df68f68178acc2db0926370e95c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 28 Apr 2006 14:30:59 +0000 Subject: Cleanup main function declarations --- tools/hcitool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 2ad26bfe..594c2601 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -2081,7 +2081,7 @@ static struct option main_options[] = { { 0, 0, 0, 0 } }; -int main(int argc, char **argv) +int main(int argc, char *argv[]) { int opt, i, dev_id = -1; bdaddr_t ba; -- cgit From 9fab0f8bb8c38b57d9a3bfe6abb2d93134326462 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 17 Jun 2006 10:35:00 +0000 Subject: Only read remote extended features if local adapter supports it --- tools/hcitool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 594c2601..f38fd1d0 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -833,7 +833,7 @@ static void cmd_info(int dev_id, int argc, char **argv) bt_free(tmp); } - if (features[7] & LMP_EXT_FEAT) { + if ((di.features[7] & LMP_EXT_FEAT) && (features[7] & LMP_EXT_FEAT)) { if (hci_read_remote_ext_features(dd, handle, 0, &max_page, features, 20000) == 0) if (max_page > 0) printf("\tExtended features: %d pages\n", max_page); -- cgit From ff9745b2228bfb780f5d5d553a8de61a7271062d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 26 Jul 2006 13:03:54 +0000 Subject: Make use of create_name() --- tools/hcitool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index f38fd1d0..ef33440f 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -281,7 +281,7 @@ static char *get_device_name(const bdaddr_t *local, const bdaddr_t *peer) char filename[PATH_MAX + 1], addr[18]; ba2str(local, addr); - snprintf(filename, PATH_MAX, "%s/%s/names", STORAGEDIR, addr); + create_name(filename, PATH_MAX, STORAGEDIR, addr, "names"); ba2str(peer, addr); return textfile_get(filename, addr); -- cgit From a229e05f0a28860e766034f04ca5086f0e355045 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 3 Sep 2006 10:53:18 +0000 Subject: Add support for periodic inquiry mode --- tools/hcitool.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 132 insertions(+), 16 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index ef33440f..4ae4226d 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -301,6 +301,7 @@ static char *dev_help = static void cmd_dev(int dev_id, int argc, char **argv) { int opt; + for_each_opt(opt, dev_options, NULL) { switch (opt) { default: @@ -310,6 +311,7 @@ static void cmd_dev(int dev_id, int argc, char **argv) } printf("Devices:\n"); + hci_for_each_dev(HCI_UP, dev_info, 0); } @@ -379,6 +381,7 @@ static void cmd_inq(int dev_id, int argc, char **argv) } printf("Inquiring ...\n"); + num_rsp = hci_inquiry(dev_id, length, num_rsp, lap, &info, flags); if (num_rsp < 0) { perror("Inquiry failed."); @@ -658,8 +661,9 @@ static void cmd_scan(int dev_id, int argc, char **argv) printf("\n"); } - close(dd); bt_free(info); + + hci_close_dev(dd); } /* Remote name */ @@ -713,7 +717,7 @@ static void cmd_name(int dev_id, int argc, char **argv) if (hci_read_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0) printf("%s\n", name); - close(dd); + hci_close_dev(dd); } /* Info about remote device */ @@ -844,7 +848,104 @@ static void cmd_info(int dev_id, int argc, char **argv) hci_disconnect(dd, handle, HCI_OE_USER_ENDED_CONNECTION, 10000); } - close(dd); + hci_close_dev(dd); +} + +/* Start periodic inquiry */ + +static struct option spinq_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static char *spinq_help = + "Usage:\n" + "\tspinq\n"; + +static void cmd_spinq(int dev_id, int argc, char **argv) +{ + uint8_t lap[3] = { 0x33, 0x8b, 0x9e }; + struct hci_request rq; + periodic_inquiry_cp cp; + int opt, dd; + + for_each_opt(opt, spinq_options, NULL) { + switch (opt) { + default: + printf(spinq_help); + return; + } + } + + if (dev_id < 0) + dev_id = hci_get_route(NULL); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("Device open failed"); + exit(EXIT_FAILURE); + } + + memset(&cp, 0, sizeof(cp)); + memcpy(cp.lap, lap, 3); + cp.max_period = 16; + cp.min_period = 10; + cp.length = 8; + cp.num_rsp = 0; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_PERIODIC_INQUIRY; + rq.cparam = &cp; + rq.clen = PERIODIC_INQUIRY_CP_SIZE; + + if (hci_send_req(dd, &rq, 100) < 0) { + perror("Periodic inquiry failed"); + exit(EXIT_FAILURE); + } + + hci_close_dev(dd); +} + +/* Exit periodic inquiry */ + +static struct option epinq_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static char *epinq_help = + "Usage:\n" + "\tspinq\n"; + +static void cmd_epinq(int dev_id, int argc, char **argv) +{ + int opt, dd; + + for_each_opt(opt, epinq_options, NULL) { + switch (opt) { + default: + printf(epinq_help); + return; + } + } + + if (dev_id < 0) + dev_id = hci_get_route(NULL); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("Device open failed"); + exit(EXIT_FAILURE); + } + + if (hci_send_cmd(dd, OGF_LINK_CTL, + OCF_EXIT_PERIODIC_INQUIRY, 0, NULL) < 0) { + perror("Exit periodic inquiry failed"); + exit(EXIT_FAILURE); + } + + hci_close_dev(dd); } /* Send arbitrary HCI commands */ @@ -961,6 +1062,7 @@ static void cmd_con(int dev_id, int argc, char **argv) } printf("Connections:\n"); + hci_for_each_dev(HCI_UP, conn_list, dev_id); } @@ -1033,6 +1135,7 @@ static void cmd_cc(int dev_id, int argc, char **argv) if (hci_create_connection(dd, &bdaddr, htobs(ptype), htobs(0x0000), role, &handle, 25000) < 0) perror("Can't create connection"); + hci_close_dev(dd); } @@ -1101,8 +1204,9 @@ static void cmd_dc(int dev_id, int argc, char **argv) HCI_OE_USER_ENDED_CONNECTION, 10000) < 0) perror("Disconnect failed"); - close(dd); free(cr); + + hci_close_dev(dd); } /* Role switch */ @@ -1169,7 +1273,7 @@ static void cmd_sr(int dev_id, int argc, char **argv) exit(1); } - close(dd); + hci_close_dev(dd); } /* Read RSSI */ @@ -1241,8 +1345,9 @@ static void cmd_rssi(int dev_id, int argc, char **argv) printf("RSSI return value: %d\n", rssi); - close(dd); free(cr); + + hci_close_dev(dd); } /* Get link quality */ @@ -1314,8 +1419,9 @@ static void cmd_lq(int dev_id, int argc, char **argv) printf("Link quality: %d\n", lq); - close(dd); free(cr); + + hci_close_dev(dd); } /* Get transmit power level */ @@ -1390,8 +1496,9 @@ static void cmd_tpl(int dev_id, int argc, char **argv) printf("%s transmit power level: %d\n", (type == 0) ? "Current" : "Maximum", level); - close(dd); free(cr); + + hci_close_dev(dd); } /* Get AFH channel map */ @@ -1473,8 +1580,9 @@ static void cmd_afh(int dev_id, int argc, char **argv) } else printf("AFH disabled\n"); - close(dd); free(cr); + + hci_close_dev(dd); } /* Set connection packet type */ @@ -1560,8 +1668,9 @@ static void cmd_cpt(int dev_id, int argc, char **argv) exit(1); } - close(dd); free(cr); + + hci_close_dev(dd); } /* Get/Set link supervision timeout */ @@ -1648,8 +1757,9 @@ static void cmd_lst(int dev_id, int argc, char **argv) } } - close(dd); free(cr); + + hci_close_dev(dd); } /* Request authentication */ @@ -1718,8 +1828,9 @@ static void cmd_auth(int dev_id, int argc, char **argv) exit(1); } - close(dd); free(cr); + + hci_close_dev(dd); } /* Activate encryption */ @@ -1791,8 +1902,9 @@ static void cmd_enc(int dev_id, int argc, char **argv) exit(1); } - close(dd); free(cr); + + hci_close_dev(dd); } /* Change connection link key */ @@ -1861,8 +1973,9 @@ static void cmd_key(int dev_id, int argc, char **argv) exit(1); } - close(dd); free(cr); + + hci_close_dev(dd); } /* Read clock offset */ @@ -1934,8 +2047,9 @@ static void cmd_clkoff(int dev_id, int argc, char **argv) printf("Clock offset: 0x%4.4x\n", btohs(offset)); - close(dd); free(cr); + + hci_close_dev(dd); } /* Read clock */ @@ -2024,7 +2138,7 @@ static void cmd_clock(int dev_id, int argc, char **argv) printf("Clock: 0x%4.4x\n", btohl(clock)); printf("Accuracy: %.2f msec\n", (float) accuracy * 0.3125); - close(dd); + hci_close_dev(dd); } static struct { @@ -2037,6 +2151,8 @@ static struct { { "scan", cmd_scan, "Scan for remote devices" }, { "name", cmd_name, "Get name from remote device" }, { "info", cmd_info, "Get information from remote device" }, + { "spinq", cmd_spinq, "Start periodic inquiry" }, + { "epinq", cmd_epinq, "Exit periodic inquiry" }, { "cmd", cmd_cmd, "Submit arbitrary HCI commands" }, { "con", cmd_con, "Display active connections" }, { "cc", cmd_cc, "Create connection to remote device" }, -- cgit From 8ee8041f8ad6aeb75ff9d9dba3d27d6663da247a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 20 Sep 2006 08:47:57 +0000 Subject: Fix endian issue with periodic inquiry --- tools/hcitool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 4ae4226d..88c320b6 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -888,8 +888,8 @@ static void cmd_spinq(int dev_id, int argc, char **argv) memset(&cp, 0, sizeof(cp)); memcpy(cp.lap, lap, 3); - cp.max_period = 16; - cp.min_period = 10; + cp.max_period = htobs(16); + cp.min_period = htobs(10); cp.length = 8; cp.num_rsp = 0; -- cgit From b08d30eb4d07eec80cd7f852a6037864219313d0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 29 Sep 2006 11:42:14 +0000 Subject: Fix major class count calculation error --- tools/hcitool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 88c320b6..dfa3e48e 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -619,7 +619,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) if (extcls) { memcpy(cls, (info+i)->dev_class, 3); printf("Device class:\t"); - if ((cls[1] & 0x1f) > sizeof(*major_classes)) + if ((cls[1] & 0x1f) > sizeof(major_classes) / sizeof(char *)) printf("Invalid"); else printf("%s, %s", major_classes[cls[1] & 0x1f], -- cgit From 59a4bc3afb004d7aeef69461987307738a9fe4af Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 26 Nov 2006 09:17:15 +0000 Subject: Use multibyte friendly checks instead of isprint() --- tools/hcitool.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index dfa3e48e..9449e7c6 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -546,9 +546,11 @@ static void cmd_scan(int dev_id, int argc, char **argv) sizeof(name), name, 100000) < 0) strcpy(name, "n/a"); - for (n = 0; n < 248 && name[n]; n++) - if (!isprint(name[n])) - name[n] = '.'; + for (n = 0; n < 248 && name[n]; n++) { + if ((unsigned char) name[i] < 32 || name[i] == 127) + name[i] = '.'; + } + name[248] = '\0'; printf("\t%s\t%s\n", addr, name); @@ -605,9 +607,11 @@ static void cmd_scan(int dev_id, int argc, char **argv) if (!nc) strcpy(name, "n/a"); } else { - for (n = 0; n < 248 && name[n]; n++) - if (!isprint(name[n])) - name[n] = '.'; + for (n = 0; n < 248 && name[n]; n++) { + if ((unsigned char) name[i] < 32 || name[i] == 127) + name[i] = '.'; + } + name[248] = '\0'; nc = 0; } -- cgit From f1e35f0b9edc15eebfd9b2b0b01ffa4bf0f85cdb Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 20 Dec 2006 10:40:46 +0000 Subject: More accurate class of device decoding for hcitool and hciconfig --- tools/hcitool.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 68 insertions(+), 5 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 9449e7c6..50abce17 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -245,16 +245,51 @@ static char *get_minor_device_name(int major, int minor) return "Gaming/Toy"; } break; - case 5: /* peripheral */ - switch(minor) { + case 5: /* peripheral */ { + static char cls_str[48]; cls_str[0] = 0; + + switch(minor & 48) { case 16: - return "Keyboard"; + strncpy(cls_str, "Keyboard", sizeof(cls_str)); + break; case 32: - return "Pointing device"; + strncpy(cls_str, "Pointing device", sizeof(cls_str)); + break; case 48: - return "Combo keyboard/pointing device"; + strncpy(cls_str, "Combo keyboard/pointing device", sizeof(cls_str)); + break; } + if((minor & 15) && (strlen(cls_str) > 0)) + strcat(cls_str, "/"); + + switch(minor & 15) { + case 0: + break; + case 1: + strncat(cls_str, "Joystick", sizeof(cls_str) - strlen(cls_str)); + break; + case 2: + strncat(cls_str, "Gamepad", sizeof(cls_str) - strlen(cls_str)); + break; + case 3: + strncat(cls_str, "Remote control", sizeof(cls_str) - strlen(cls_str)); + break; + case 4: + strncat(cls_str, "Sensing device", sizeof(cls_str) - strlen(cls_str)); + break; + case 5: + strncat(cls_str, "Digitizer tablet", sizeof(cls_str) - strlen(cls_str)); break; + case 6: + strncat(cls_str, "Card reader", sizeof(cls_str) - strlen(cls_str)); + break; + default: + strncat(cls_str, "(reserved)", sizeof(cls_str) - strlen(cls_str)); + break; + } + if(strlen(cls_str) > 0) + return cls_str; + } case 6: /* imaging */ if (minor & 4) return "Display"; @@ -265,6 +300,34 @@ static char *get_minor_device_name(int major, int minor) if (minor & 32) return "Printer"; break; + case 7: /* wearable */ + switch(minor) { + case 1: + return "Wrist Watch"; + case 2: + return "Pager"; + case 3: + return "Jacket"; + case 4: + return "Helmet"; + case 5: + return "Glasses"; + } + break; + case 8: /* toy */ + switch(minor) { + case 1: + return "Robot"; + case 2: + return "Vehicle"; + case 3: + return "Doll / Action Figure"; + case 4: + return "Controller"; + case 5: + return "Game"; + } + break; case 63: /* uncategorised */ return ""; } -- cgit From 607695ed109340f4b7a5628420e0a8e8aee34f4e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 13 Jan 2007 17:48:12 +0000 Subject: Update copyright information --- tools/hcitool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 50abce17..75fbc8e2 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2006 Marcel Holtmann + * Copyright (C) 2002-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify -- cgit From 5542ce34cfb07a75eebd5659fb66d1fe2394faa6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 16 Jun 2007 11:31:41 +0000 Subject: Fix decoding of extended pages number --- tools/hcitool.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 75fbc8e2..49cc6fe6 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -905,9 +905,11 @@ static void cmd_info(int dev_id, int argc, char **argv) } if ((di.features[7] & LMP_EXT_FEAT) && (features[7] & LMP_EXT_FEAT)) { - if (hci_read_remote_ext_features(dd, handle, 0, &max_page, features, 20000) == 0) + if (hci_read_remote_ext_features(dd, handle, 0, + &max_page, features, 20000) == 0) if (max_page > 0) - printf("\tExtended features: %d pages\n", max_page); + printf("\tExtended features: %d page%s\n", + max_page, max_page > 1 ? "s" : ""); } if (cc) { -- cgit From 7d7658ad2fcd296440916cd26cd8182a8dc0a7c3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 10 Sep 2007 18:47:30 +0000 Subject: Show connection link type correctly --- tools/hcitool.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 49cc6fe6..c9d3dbd6 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -63,6 +63,20 @@ static int dev_info(int s, int dev_id, long arg) return 0; } +static char *type2str(uint8_t type) +{ + switch (type) { + case SCO_LINK: + return "SCO"; + case ACL_LINK: + return "ACL"; + case ESCO_LINK: + return "eSCO"; + default: + return "Unknown"; + } +} + static int conn_list(int s, int dev_id, long arg) { struct hci_conn_list_req *cl; @@ -90,8 +104,7 @@ static int conn_list(int s, int dev_id, long arg) char addr[18]; ba2str(&ci->bdaddr, addr); printf("\t%s %s %s handle %d state %d lm %s\n", - ci->out ? "<" : ">", - ci->type == ACL_LINK ? "ACL" : "SCO", + ci->out ? "<" : ">", type2str(ci->type), addr, ci->handle, ci->state, hci_lmtostr(ci->link_mode)); } -- cgit From 6efce5841c487a4fbbc0aa324cbcdd1d58f40077 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 14 Sep 2007 11:25:34 +0000 Subject: Add refresh option to re-request device names --- tools/hcitool.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index c9d3dbd6..ec043d6e 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -484,6 +484,7 @@ static struct option scan_options[] = { { "numrsp", 1, 0, 'n' }, { "iac", 1, 0, 'i' }, { "flush", 0, 0, 'f' }, + { "refresh", 0, 0, 'r' }, { "class", 0, 0, 'C' }, { "info", 0, 0, 'I' }, { "oui", 0, 0, 'O' }, @@ -494,7 +495,7 @@ static struct option scan_options[] = { static char *scan_help = "Usage:\n" - "\tscan [--length=N] [--numrsp=N] [--iac=lap] [--flush] [--class] [--info] [--oui]\n"; + "\tscan [--length=N] [--numrsp=N] [--iac=lap] [--flush] [--class] [--info] [--oui] [--refresh]\n"; static void cmd_scan(int dev_id, int argc, char **argv) { @@ -507,7 +508,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) struct hci_version version; struct hci_dev_info di; struct hci_conn_info_req *cr; - int extcls = 0, extinf = 0, extoui = 0; + int refresh = 0, extcls = 0, extinf = 0, extoui = 0; int i, n, l, opt, dd, cc, nc; length = 8; /* ~10 seconds */ @@ -543,6 +544,10 @@ static void cmd_scan(int dev_id, int argc, char **argv) flags |= IREQ_CACHE_FLUSH; break; + case 'r': + refresh = 1; + break; + case 'C': extcls = 1; break; @@ -598,12 +603,15 @@ static void cmd_scan(int dev_id, int argc, char **argv) printf("\n"); for (i = 0; i < num_rsp; i++) { - memset(name, 0, sizeof(name)); - tmp = get_device_name(&di.bdaddr, &(info+i)->bdaddr); - if (tmp) { - strncpy(name, tmp, 249); - free(tmp); - nc = 1; + if (!refresh) { + memset(name, 0, sizeof(name)); + tmp = get_device_name(&di.bdaddr, &(info+i)->bdaddr); + if (tmp) { + strncpy(name, tmp, 249); + free(tmp); + nc = 1; + } else + nc = 0; } else nc = 0; -- cgit From e823c15e43a6f924779e466d434c51157002d9ee Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 2 Feb 2008 03:37:05 +0000 Subject: Update copyright information --- tools/hcitool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index ec043d6e..60e196be 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2007 Marcel Holtmann + * Copyright (C) 2002-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify -- cgit From bbd957c4d906e3107b892b72339716f77c6b4b04 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 12 Jun 2008 21:53:32 +0000 Subject: Add support for reading/setting the link policy --- tools/hcitool.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 105 insertions(+), 3 deletions(-) (limited to 'tools/hcitool.c') diff --git a/tools/hcitool.c b/tools/hcitool.c index 60e196be..02f56a43 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1763,6 +1763,105 @@ static void cmd_cpt(int dev_id, int argc, char **argv) hci_close_dev(dd); } +/* Get/Set link policy settings */ + +static struct option lp_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static char *lp_help = + "Usage:\n" + "\tlp [link policy]\n"; + +static void cmd_lp(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + bdaddr_t bdaddr; + uint16_t policy; + int opt, dd; + + for_each_opt(opt, lp_options, NULL) { + switch (opt) { + default: + printf(lp_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(lp_help); + return; + } + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + if (argc == 1) { + char *str; + if (hci_read_link_policy(dd, htobs(cr->conn_info->handle), + &policy, 1000) < 0) { + perror("HCI read_link_policy_settings request failed"); + exit(1); + } + + policy = btohs(policy); + str = hci_lptostr(policy); + if (str) { + printf("Link policy settings: %s\n", str); + bt_free(str); + } else { + fprintf(stderr, "Invalig settings\n"); + exit(1); + } + } else { + unsigned int val; + if (hci_strtolp(argv[1], &val) < 0) { + fprintf(stderr, "Invalig arguments\n"); + exit(1); + } + policy = val; + + if (hci_write_link_policy(dd, htobs(cr->conn_info->handle), + htobs(policy), 1000) < 0) { + perror("HCI write_link_policy_settings request failed"); + exit(1); + } + } + + free(cr); + + hci_close_dev(dd); +} + /* Get/Set link supervision timeout */ static struct option lst_options[] = { @@ -1826,7 +1925,8 @@ static void cmd_lst(int dev_id, int argc, char **argv) } if (argc == 1) { - if (hci_read_link_supervision_timeout(dd, htobs(cr->conn_info->handle), &timeout, 1000) < 0) { + if (hci_read_link_supervision_timeout(dd, htobs(cr->conn_info->handle), + &timeout, 1000) < 0) { perror("HCI read_link_supervision_timeout request failed"); exit(1); } @@ -1839,9 +1939,10 @@ static void cmd_lst(int dev_id, int argc, char **argv) else printf("Link supervision timeout never expires\n"); } else { - timeout = btohs(strtol(argv[1], NULL, 10)); + timeout = strtol(argv[1], NULL, 10); - if (hci_write_link_supervision_timeout(dd, htobs(cr->conn_info->handle), timeout, 1000) < 0) { + if (hci_write_link_supervision_timeout(dd, htobs(cr->conn_info->handle), + htobs(timeout), 1000) < 0) { perror("HCI write_link_supervision_timeout request failed"); exit(1); } @@ -2253,6 +2354,7 @@ static struct { { "lq", cmd_lq, "Display link quality" }, { "tpl", cmd_tpl, "Display transmit power level" }, { "afh", cmd_afh, "Display AFH channel map" }, + { "lp", cmd_lp, "Set/display link policy settings" }, { "lst", cmd_lst, "Set/display link supervision timeout" }, { "auth", cmd_auth, "Request authentication" }, { "enc", cmd_enc, "Set connection encryption" }, -- cgit