Sat Aug 27 22:22:01 2011 UTC ()
static + __dead


(joerg)
diff -r1.24 -r1.25 src/usr.sbin/btconfig/btconfig.c

cvs diff -r1.24 -r1.25 src/usr.sbin/btconfig/btconfig.c (expand / switch to unified diff)

--- src/usr.sbin/btconfig/btconfig.c 2010/11/28 20:37:24 1.24
+++ src/usr.sbin/btconfig/btconfig.c 2011/08/27 22:22:01 1.25
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: btconfig.c,v 1.24 2010/11/28 20:37:24 plunky Exp $ */ 1/* $NetBSD: btconfig.c,v 1.25 2011/08/27 22:22:01 joerg Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2006 Itronix Inc. 4 * Copyright (c) 2006 Itronix Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Written by Iain Hibbert for Itronix Inc. 7 * Written by Iain Hibbert for Itronix Inc.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
@@ -23,152 +23,151 @@ @@ -23,152 +23,151 @@
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28 * ON ANY THEORY OF LIABILITY, WHETHER IN 28 * ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE. 31 * POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#include <sys/cdefs.h> 34#include <sys/cdefs.h>
35__COPYRIGHT("@(#) Copyright (c) 2006 Itronix, Inc. All rights reserved."); 35__COPYRIGHT("@(#) Copyright (c) 2006 Itronix, Inc. All rights reserved.");
36__RCSID("$NetBSD: btconfig.c,v 1.24 2010/11/28 20:37:24 plunky Exp $"); 36__RCSID("$NetBSD: btconfig.c,v 1.25 2011/08/27 22:22:01 joerg Exp $");
37 37
38#include <sys/ioctl.h> 38#include <sys/ioctl.h>
39#include <sys/param.h> 39#include <sys/param.h>
40#include <sys/socket.h> 40#include <sys/socket.h>
41 41
42#include <bluetooth.h> 42#include <bluetooth.h>
43#include <err.h> 43#include <err.h>
44#include <errno.h> 44#include <errno.h>
45#include <stdio.h> 45#include <stdio.h>
46#include <stdlib.h> 46#include <stdlib.h>
47#include <string.h> 47#include <string.h>
48#include <time.h> 48#include <time.h>
49#include <unistd.h> 49#include <unistd.h>
50#include <util.h> 50#include <util.h>
51 51
52int main(int, char *[]); 52__dead static void badarg(const char *);
53void badarg(const char *); 53__dead static void badparam(const char *);
54void badparam(const char *); 54__dead static void badval(const char *, const char *);
55void badval(const char *, const char *); 55__dead static void usage(void);
56void usage(void); 56static int set_unit(unsigned long);
57int set_unit(unsigned long); 57static void config_unit(void);
58void config_unit(void); 58static void print_val(const char *, const char **, int);
59void print_val(const char *, const char **, int); 59static void print_info(int);
60void print_info(int); 60static void print_stats(void);
61void print_stats(void); 61static void print_class(const char *, uint8_t *);
62void print_class(const char *, uint8_t *); 62static void print_class0(void);
63void print_class0(void); 63static void print_voice(int);
64void print_voice(int); 64static void tag(const char *);
65void tag(const char *); 65static void print_features0(uint8_t *);
66void print_features0(uint8_t *); 66static void print_features1(uint8_t *);
67void print_features1(uint8_t *); 67static void print_result(int, struct bt_devinquiry *);
68void print_result(int, struct bt_devinquiry *); 68static void do_inquiry(void);
69void do_inquiry(void); 69
70 70static void hci_req(uint16_t, uint8_t , void *, size_t, void *, size_t);
71void hci_req(uint16_t, uint8_t , void *, size_t, void *, size_t); 71static void save_value(uint16_t, void *, size_t);
72void save_value(uint16_t, void *, size_t); 72static void load_value(uint16_t, void *, size_t);
73void load_value(uint16_t, void *, size_t); 
74 73
75#define MAX_STR_SIZE 0xff 74#define MAX_STR_SIZE 0xff
76 75
77/* print width */ 76/* print width */
78int width = 0; 77static int width = 0;
79#define MAX_WIDTH 70 78#define MAX_WIDTH 70
80 79
81/* global variables */ 80/* global variables */
82int hci; 81static int hci;
83struct btreq btr; 82static struct btreq btr;
84 83
85/* command line flags */ 84/* command line flags */
86int verbose = 0; /* more info */ 85static int verbose = 0; /* more info */
87int lflag = 0; /* list devices */ 86static int lflag = 0; /* list devices */
88int sflag = 0; /* get/zero stats */ 87static int sflag = 0; /* get/zero stats */
89 88
90/* device up/down (flag) */ 89/* device up/down (flag) */
91int opt_enable = 0; 90static int opt_enable = 0;
92int opt_reset = 0; 91static int opt_reset = 0;
93#define FLAGS_FMT "\20" \ 92#define FLAGS_FMT "\20" \
94 "\001UP" \ 93 "\001UP" \
95 "\002RUNNING" \ 94 "\002RUNNING" \
96 "\003XMIT_CMD" \ 95 "\003XMIT_CMD" \
97 "\004XMIT_ACL" \ 96 "\004XMIT_ACL" \
98 "\005XMIT_SCO" \ 97 "\005XMIT_SCO" \
99 "\006INIT_BDADDR" \ 98 "\006INIT_BDADDR" \
100 "\007INIT_BUFFER_SIZE" \ 99 "\007INIT_BUFFER_SIZE" \
101 "\010INIT_FEATURES" \ 100 "\010INIT_FEATURES" \
102 "\011POWER_UP_NOOP" \ 101 "\011POWER_UP_NOOP" \
103 "\012INIT_COMMANDS" \ 102 "\012INIT_COMMANDS" \
104 "\013MASTER" \ 103 "\013MASTER" \
105 "" 104 ""
106 105
107/* authorisation (flag) */ 106/* authorisation (flag) */
108int opt_auth = 0; 107static int opt_auth = 0;
109 108
110/* encryption (flag) */ 109/* encryption (flag) */
111int opt_encrypt = 0; 110static int opt_encrypt = 0;
112 111
113/* scan enable options (flags) */ 112/* scan enable options (flags) */
114int opt_pscan = 0; 113static int opt_pscan = 0;
115int opt_iscan = 0; 114static int opt_iscan = 0;
116 115
117/* master role option */ 116/* master role option */
118int opt_master = 0; 117static int opt_master = 0;
119 118
120/* link policy options (flags) */ 119/* link policy options (flags) */
121int opt_switch = 0; 120static int opt_switch = 0;
122int opt_hold = 0; 121static int opt_hold = 0;
123int opt_sniff = 0; 122static int opt_sniff = 0;
124int opt_park = 0; 123static int opt_park = 0;
125 124
126/* class of device (hex value) */ 125/* class of device (hex value) */
127int opt_class = 0; 126static int opt_class = 0;
128uint32_t class; 127static uint32_t class;
129 128
130/* packet type mask (hex value) */ 129/* packet type mask (hex value) */
131int opt_ptype = 0; 130static int opt_ptype = 0;
132uint32_t ptype; 131static uint32_t ptype;
133 132
134/* unit name (string) */ 133/* unit name (string) */
135int opt_name = 0; 134static int opt_name = 0;
136char name[MAX_STR_SIZE]; 135static char name[MAX_STR_SIZE];
137 136
138/* pin type */ 137/* pin type */
139int opt_pin = 0; 138static int opt_pin = 0;
140 139
141/* Inquiry */ 140/* Inquiry */
142int opt_rssi = 0; /* inquiry_with_rssi (obsolete flag) */ 141static int opt_rssi = 0; /* inquiry_with_rssi (obsolete flag) */
143int opt_imode = 0; /* inquiry mode */ 142static int opt_imode = 0; /* inquiry mode */
144int opt_inquiry = 0; 143static int opt_inquiry = 0;
145#define INQUIRY_LENGTH 10 /* seconds */ 144#define INQUIRY_LENGTH 10 /* seconds */
146#define INQUIRY_MAX_RESPONSES 10 145#define INQUIRY_MAX_RESPONSES 10
147const char *imodes[] = { "std", "rssi", "ext", NULL }; 146static const char *imodes[] = { "std", "rssi", "ext", NULL };
148 147
149/* Voice Settings */ 148/* Voice Settings */
150int opt_voice = 0; 149static int opt_voice = 0;
151uint32_t voice; 150static uint32_t voice;
152 151
153/* Page Timeout */ 152/* Page Timeout */
154int opt_pto = 0; 153static int opt_pto = 0;
155uint32_t pto; 154static uint32_t pto;
156 155
157/* set SCO mtu */ 156/* set SCO mtu */
158int opt_scomtu; 157static int opt_scomtu;
159uint32_t scomtu; 158static uint32_t scomtu;
160 159
161struct parameter { 160static struct parameter {
162 const char *name; 161 const char *name;
163 enum { P_SET, P_CLR, P_STR, P_HEX, P_NUM, P_VAL } type; 162 enum { P_SET, P_CLR, P_STR, P_HEX, P_NUM, P_VAL } type;
164 int *opt; 163 int *opt;
165 void *val; 164 void *val;
166} parameters[] = { 165} parameters[] = {
167 { "up", P_SET, &opt_enable, NULL }, 166 { "up", P_SET, &opt_enable, NULL },
168 { "enable", P_SET, &opt_enable, NULL }, 167 { "enable", P_SET, &opt_enable, NULL },
169 { "down", P_CLR, &opt_enable, NULL }, 168 { "down", P_CLR, &opt_enable, NULL },
170 { "disable", P_CLR, &opt_enable, NULL }, 169 { "disable", P_CLR, &opt_enable, NULL },
171 { "name", P_STR, &opt_name, name }, 170 { "name", P_STR, &opt_name, name },
172 { "pscan", P_SET, &opt_pscan, NULL }, 171 { "pscan", P_SET, &opt_pscan, NULL },
173 { "-pscan", P_CLR, &opt_pscan, NULL }, 172 { "-pscan", P_CLR, &opt_pscan, NULL },
174 { "iscan", P_SET, &opt_iscan, NULL }, 173 { "iscan", P_SET, &opt_iscan, NULL },
@@ -313,161 +312,161 @@ main(int ac, char *av[]) @@ -313,161 +312,161 @@ main(int ac, char *av[])
313 av++, ac--; 312 av++, ac--;
314 } 313 }
315 314
316 config_unit(); 315 config_unit();
317 print_info(verbose); 316 print_info(verbose);
318 print_stats(); 317 print_stats();
319 do_inquiry(); 318 do_inquiry();
320 } 319 }
321 320
322 close(hci); 321 close(hci);
323 return EXIT_SUCCESS; 322 return EXIT_SUCCESS;
324} 323}
325 324
326void 325static void
327badparam(const char *param) 326badparam(const char *param)
328{ 327{
329 328
330 fprintf(stderr, "unknown parameter '%s'\n", param); 329 fprintf(stderr, "unknown parameter '%s'\n", param);
331 exit(EXIT_FAILURE); 330 exit(EXIT_FAILURE);
332} 331}
333 332
334void 333static void
335badarg(const char *param) 334badarg(const char *param)
336{ 335{
337 336
338 fprintf(stderr, "parameter '%s' needs argument\n", param); 337 fprintf(stderr, "parameter '%s' needs argument\n", param);
339 exit(EXIT_FAILURE); 338 exit(EXIT_FAILURE);
340} 339}
341 340
342void 341static void
343badval(const char *param, const char *value) 342badval(const char *param, const char *value)
344{ 343{
345 344
346 fprintf(stderr, "bad value '%s' for parameter '%s'\n", value, param); 345 fprintf(stderr, "bad value '%s' for parameter '%s'\n", value, param);
347 exit(EXIT_FAILURE); 346 exit(EXIT_FAILURE);
348} 347}
349 348
350void 349static void
351usage(void) 350usage(void)
352{ 351{
353 352
354 fprintf(stderr, "usage: %s [-svz] [device [parameters]]\n", getprogname()); 353 fprintf(stderr, "usage: %s [-svz] [device [parameters]]\n", getprogname());
355 fprintf(stderr, " %s -l\n", getprogname()); 354 fprintf(stderr, " %s -l\n", getprogname());
356 exit(EXIT_FAILURE); 355 exit(EXIT_FAILURE);
357} 356}
358 357
359/* 358/*
360 * pretty printing feature 359 * pretty printing feature
361 */ 360 */
362void 361static void
363tag(const char *f) 362tag(const char *f)
364{ 363{
365 364
366 if (f == NULL) { 365 if (f == NULL) {
367 if (width > 0) 366 if (width > 0)
368 printf("\n"); 367 printf("\n");
369 368
370 width = 0; 369 width = 0;
371 } else { 370 } else {
372 width += printf("%*s%s", 371 width += printf("%*s%s",
373 (width == 0 ? (lflag ? 0 : 8) : 1), 372 (width == 0 ? (lflag ? 0 : 8) : 1),
374 "", f); 373 "", f);
375 374
376 if (width > MAX_WIDTH) { 375 if (width > MAX_WIDTH) {
377 printf("\n"); 376 printf("\n");
378 width = 0; 377 width = 0;
379 } 378 }
380 } 379 }
381} 380}
382 381
383/* 382/*
384 * basic HCI request wrapper with error check 383 * basic HCI request wrapper with error check
385 */ 384 */
386void 385static void
387hci_req(uint16_t opcode, uint8_t event, void *cbuf, size_t clen, 386hci_req(uint16_t opcode, uint8_t event, void *cbuf, size_t clen,
388 void *rbuf, size_t rlen) 387 void *rbuf, size_t rlen)
389{ 388{
390 struct bt_devreq req; 389 struct bt_devreq req;
391 390
392 req.opcode = opcode; 391 req.opcode = opcode;
393 req.event = event; 392 req.event = event;
394 req.cparam = cbuf; 393 req.cparam = cbuf;
395 req.clen = clen; 394 req.clen = clen;
396 req.rparam = rbuf; 395 req.rparam = rbuf;
397 req.rlen = rlen; 396 req.rlen = rlen;
398 397
399 if (bt_devreq(hci, &req, 10) == -1) 398 if (bt_devreq(hci, &req, 10) == -1)
400 err(EXIT_FAILURE, "cmd (%02x|%03x)", 399 err(EXIT_FAILURE, "cmd (%02x|%03x)",
401 HCI_OGF(opcode), HCI_OCF(opcode)); 400 HCI_OGF(opcode), HCI_OCF(opcode));
402 401
403 if (event == 0 && rlen > 0 && ((uint8_t *)rbuf)[0] != 0) 402 if (event == 0 && rlen > 0 && ((uint8_t *)rbuf)[0] != 0)
404 errx(EXIT_FAILURE, "cmd (%02x|%03x): status 0x%02x", 403 errx(EXIT_FAILURE, "cmd (%02x|%03x): status 0x%02x",
405 HCI_OGF(opcode), HCI_OCF(opcode), ((uint8_t *)rbuf)[0]); 404 HCI_OGF(opcode), HCI_OCF(opcode), ((uint8_t *)rbuf)[0]);
406} 405}
407 406
408/* 407/*
409 * write value to device with opcode. 408 * write value to device with opcode.
410 * provide a small response buffer so that the status can be checked 409 * provide a small response buffer so that the status can be checked
411 */ 410 */
412void 411static void
413save_value(uint16_t opcode, void *cbuf, size_t clen) 412save_value(uint16_t opcode, void *cbuf, size_t clen)
414{ 413{
415 uint8_t buf[1]; 414 uint8_t buf[1];
416 415
417 hci_req(opcode, 0, cbuf, clen, buf, sizeof(buf)); 416 hci_req(opcode, 0, cbuf, clen, buf, sizeof(buf));
418} 417}
419 418
420/* 419/*
421 * read value from device with opcode. 420 * read value from device with opcode.
422 * use our own buffer and only return the value from the response packet 421 * use our own buffer and only return the value from the response packet
423 */ 422 */
424void 423static void
425load_value(uint16_t opcode, void *rbuf, size_t rlen) 424load_value(uint16_t opcode, void *rbuf, size_t rlen)
426{ 425{
427 uint8_t buf[UINT8_MAX]; 426 uint8_t buf[UINT8_MAX];
428 427
429 hci_req(opcode, 0, NULL, 0, buf, sizeof(buf)); 428 hci_req(opcode, 0, NULL, 0, buf, sizeof(buf));
430 memcpy(rbuf, buf + 1, rlen); 429 memcpy(rbuf, buf + 1, rlen);
431} 430}
432 431
433int 432static int
434set_unit(unsigned long cmd) 433set_unit(unsigned long cmd)
435{ 434{
436 435
437 if (ioctl(hci, cmd, &btr) == -1) 436 if (ioctl(hci, cmd, &btr) == -1)
438 return -1; 437 return -1;
439 438
440 if (btr.btr_flags & BTF_UP) { 439 if (btr.btr_flags & BTF_UP) {
441 struct sockaddr_bt sa; 440 struct sockaddr_bt sa;
442 441
443 sa.bt_len = sizeof(sa); 442 sa.bt_len = sizeof(sa);
444 sa.bt_family = AF_BLUETOOTH; 443 sa.bt_family = AF_BLUETOOTH;
445 bdaddr_copy(&sa.bt_bdaddr, &btr.btr_bdaddr); 444 bdaddr_copy(&sa.bt_bdaddr, &btr.btr_bdaddr);
446 445
447 if (bind(hci, (struct sockaddr *)&sa, sizeof(sa)) < 0) 446 if (bind(hci, (struct sockaddr *)&sa, sizeof(sa)) < 0)
448 err(EXIT_FAILURE, "bind"); 447 err(EXIT_FAILURE, "bind");
449 448
450 if (connect(hci, (struct sockaddr *)&sa, sizeof(sa)) < 0) 449 if (connect(hci, (struct sockaddr *)&sa, sizeof(sa)) < 0)
451 err(EXIT_FAILURE, "connect"); 450 err(EXIT_FAILURE, "connect");
452 } 451 }
453 452
454 return 0; 453 return 0;
455} 454}
456 455
457/* 456/*
458 * apply configuration parameters to unit 457 * apply configuration parameters to unit
459 */ 458 */
460void 459static void
461config_unit(void) 460config_unit(void)
462{ 461{
463 462
464 if (opt_enable) { 463 if (opt_enable) {
465 if (opt_enable > 0) 464 if (opt_enable > 0)
466 btr.btr_flags |= BTF_UP; 465 btr.btr_flags |= BTF_UP;
467 else 466 else
468 btr.btr_flags &= ~BTF_UP; 467 btr.btr_flags &= ~BTF_UP;
469 468
470 if (ioctl(hci, SIOCSBTFLAGS, &btr) < 0) 469 if (ioctl(hci, SIOCSBTFLAGS, &btr) < 0)
471 err(EXIT_FAILURE, "SIOCSBTFLAGS"); 470 err(EXIT_FAILURE, "SIOCSBTFLAGS");
472 471
473 if (set_unit(SIOCGBTINFO) < 0) 472 if (set_unit(SIOCGBTINFO) < 0)
@@ -596,41 +595,41 @@ config_unit(void) @@ -596,41 +595,41 @@ config_unit(void)
596 if (opt_imode | opt_rssi) { 595 if (opt_imode | opt_rssi) {
597 uint8_t val = (opt_rssi > 0 ? 1 : 0); 596 uint8_t val = (opt_rssi > 0 ? 1 : 0);
598 597
599 if (opt_imode) 598 if (opt_imode)
600 val = opt_imode - 1; 599 val = opt_imode - 1;
601 600
602 save_value(HCI_CMD_WRITE_INQUIRY_MODE, &val, sizeof(val)); 601 save_value(HCI_CMD_WRITE_INQUIRY_MODE, &val, sizeof(val));
603 } 602 }
604} 603}
605 604
606/* 605/*
607 * print value from NULL terminated array given index 606 * print value from NULL terminated array given index
608 */ 607 */
609void 608static void
610print_val(const char *hdr, const char **argv, int idx) 609print_val(const char *hdr, const char **argv, int idx)
611{ 610{
612 int i = 0; 611 int i = 0;
613 612
614 while (i < idx && *argv != NULL) 613 while (i < idx && *argv != NULL)
615 i++, argv++; 614 i++, argv++;
616 615
617 printf("\t%s: %s\n", hdr, *argv == NULL ? "unknown" : *argv); 616 printf("\t%s: %s\n", hdr, *argv == NULL ? "unknown" : *argv);
618} 617}
619 618
620/* 619/*
621 * Print info for Bluetooth Device with varying verbosity levels 620 * Print info for Bluetooth Device with varying verbosity levels
622 */ 621 */
623void 622static void
624print_info(int level) 623print_info(int level)
625{ 624{
626 uint8_t version, val, buf[MAX_STR_SIZE]; 625 uint8_t version, val, buf[MAX_STR_SIZE];
627 626
628 if (lflag) { 627 if (lflag) {
629 tag(btr.btr_name); 628 tag(btr.btr_name);
630 return; 629 return;
631 } 630 }
632 631
633 if (level-- < 1) 632 if (level-- < 1)
634 return; 633 return;
635 634
636 snprintb((char *)buf, MAX_STR_SIZE, FLAGS_FMT, btr.btr_flags); 635 snprintb((char *)buf, MAX_STR_SIZE, FLAGS_FMT, btr.btr_flags);
@@ -735,54 +734,54 @@ print_info(int level) @@ -735,54 +734,54 @@ print_info(int level)
735 734
736 if (level-- < 1) 735 if (level-- < 1)
737 return; 736 return;
738 737
739 if (ioctl(hci, SIOCGBTFEAT, &btr) < 0) 738 if (ioctl(hci, SIOCGBTFEAT, &btr) < 0)
740 err(EXIT_FAILURE, "SIOCGBTFEAT"); 739 err(EXIT_FAILURE, "SIOCGBTFEAT");
741 740
742 width = printf("\tfeatures:"); 741 width = printf("\tfeatures:");
743 print_features0(btr.btr_features0); 742 print_features0(btr.btr_features0);
744 print_features1(btr.btr_features1); 743 print_features1(btr.btr_features1);
745 tag(NULL); 744 tag(NULL);
746} 745}
747 746
748void 747static void
749print_stats(void) 748print_stats(void)
750{ 749{
751 750
752 if (sflag == 0) 751 if (sflag == 0)
753 return; 752 return;
754 753
755 if (sflag == 1) { 754 if (sflag == 1) {
756 if (ioctl(hci, SIOCGBTSTATS, &btr) < 0) 755 if (ioctl(hci, SIOCGBTSTATS, &btr) < 0)
757 err(EXIT_FAILURE, "SIOCGBTSTATS"); 756 err(EXIT_FAILURE, "SIOCGBTSTATS");
758 } else { 757 } else {
759 if (ioctl(hci, SIOCZBTSTATS, &btr) < 0) 758 if (ioctl(hci, SIOCZBTSTATS, &btr) < 0)
760 err(EXIT_FAILURE, "SIOCZBTSTATS"); 759 err(EXIT_FAILURE, "SIOCZBTSTATS");
761 } 760 }
762 761
763 printf( "\tTotal bytes sent %d, recieved %d\n" 762 printf( "\tTotal bytes sent %d, recieved %d\n"
764 "\tCommands sent %d, Events received %d\n" 763 "\tCommands sent %d, Events received %d\n"
765 "\tACL data packets sent %d, received %d\n" 764 "\tACL data packets sent %d, received %d\n"
766 "\tSCO data packets sent %d, received %d\n" 765 "\tSCO data packets sent %d, received %d\n"
767 "\tInput errors %d, Output errors %d\n", 766 "\tInput errors %d, Output errors %d\n",
768 btr.btr_stats.byte_tx, btr.btr_stats.byte_rx, 767 btr.btr_stats.byte_tx, btr.btr_stats.byte_rx,
769 btr.btr_stats.cmd_tx, btr.btr_stats.evt_rx, 768 btr.btr_stats.cmd_tx, btr.btr_stats.evt_rx,
770 btr.btr_stats.acl_tx, btr.btr_stats.acl_rx, 769 btr.btr_stats.acl_tx, btr.btr_stats.acl_rx,
771 btr.btr_stats.sco_tx, btr.btr_stats.sco_rx, 770 btr.btr_stats.sco_tx, btr.btr_stats.sco_rx,
772 btr.btr_stats.err_rx, btr.btr_stats.err_tx); 771 btr.btr_stats.err_rx, btr.btr_stats.err_tx);
773} 772}
774 773
775void 774static void
776print_features0(uint8_t *f) 775print_features0(uint8_t *f)
777{ 776{
778 777
779 /* ------------------- byte 0 --------------------*/ 778 /* ------------------- byte 0 --------------------*/
780 if (*f & HCI_LMP_3SLOT) tag("<3 slot>"); 779 if (*f & HCI_LMP_3SLOT) tag("<3 slot>");
781 if (*f & HCI_LMP_5SLOT) tag("<5 slot>"); 780 if (*f & HCI_LMP_5SLOT) tag("<5 slot>");
782 if (*f & HCI_LMP_ENCRYPTION) tag("<encryption>"); 781 if (*f & HCI_LMP_ENCRYPTION) tag("<encryption>");
783 if (*f & HCI_LMP_SLOT_OFFSET) tag("<slot offset>"); 782 if (*f & HCI_LMP_SLOT_OFFSET) tag("<slot offset>");
784 if (*f & HCI_LMP_TIMIACCURACY) tag("<timing accuracy>"); 783 if (*f & HCI_LMP_TIMIACCURACY) tag("<timing accuracy>");
785 if (*f & HCI_LMP_ROLE_SWITCH) tag("<role switch>"); 784 if (*f & HCI_LMP_ROLE_SWITCH) tag("<role switch>");
786 if (*f & HCI_LMP_HOLD_MODE) tag("<hold mode>"); 785 if (*f & HCI_LMP_HOLD_MODE) tag("<hold mode>");
787 if (*f & HCI_LMP_SNIFF_MODE) tag("<sniff mode>"); 786 if (*f & HCI_LMP_SNIFF_MODE) tag("<sniff mode>");
788 f++; 787 f++;
@@ -843,50 +842,50 @@ print_features0(uint8_t *f) @@ -843,50 +842,50 @@ print_features0(uint8_t *f)
843 if (*f & HCI_LMP_SIMPLE_PAIRING) tag("<secure simple pairing>"); 842 if (*f & HCI_LMP_SIMPLE_PAIRING) tag("<secure simple pairing>");
844 if (*f & HCI_LMP_ENCAPSULATED_PDU) tag("<encapsulated PDU>"); 843 if (*f & HCI_LMP_ENCAPSULATED_PDU) tag("<encapsulated PDU>");
845 if (*f & HCI_LMP_ERRDATA_REPORTING) tag("<errdata reporting>"); 844 if (*f & HCI_LMP_ERRDATA_REPORTING) tag("<errdata reporting>");
846 if (*f & HCI_LMP_NOFLUSH_PB_FLAG) tag("<no flush PB flag>"); 845 if (*f & HCI_LMP_NOFLUSH_PB_FLAG) tag("<no flush PB flag>");
847 f++; 846 f++;
848 847
849 /* ------------------- byte 7 --------------------*/ 848 /* ------------------- byte 7 --------------------*/
850 if (*f & HCI_LMP_LINK_SUPERVISION_TO)tag("<link supervision timeout changed>"); 849 if (*f & HCI_LMP_LINK_SUPERVISION_TO)tag("<link supervision timeout changed>");
851 if (*f & HCI_LMP_INQ_RSP_TX_POWER) tag("<inquiry rsp TX power level>"); 850 if (*f & HCI_LMP_INQ_RSP_TX_POWER) tag("<inquiry rsp TX power level>");
852 if (*f & HCI_LMP_ENHANCED_POWER_CONTROL)tag("<enhanced power control>"); 851 if (*f & HCI_LMP_ENHANCED_POWER_CONTROL)tag("<enhanced power control>");
853 if (*f & HCI_LMP_EXTENDED_FEATURES) tag("<extended features>"); 852 if (*f & HCI_LMP_EXTENDED_FEATURES) tag("<extended features>");
854} 853}
855 854
856void 855static void
857print_features1(uint8_t *f) 856print_features1(uint8_t *f)
858{ 857{
859 858
860 /* ------------------- byte 0 --------------------*/ 859 /* ------------------- byte 0 --------------------*/
861 if (*f & HCI_LMP_SSP) tag("<secure simple pairing>"); 860 if (*f & HCI_LMP_SSP) tag("<secure simple pairing>");
862} 861}
863 862
864void 863static void
865print_class(const char *str, uint8_t *uclass) 864print_class(const char *str, uint8_t *uclass)
866{ 865{
867 866
868 class = (uclass[2] << 16) | (uclass[1] << 8) | uclass[0]; 867 class = (uclass[2] << 16) | (uclass[1] << 8) | uclass[0];
869 width = printf("%s [0x%06x]", str, class); 868 width = printf("%s [0x%06x]", str, class);
870 869
871 switch(__SHIFTOUT(class, __BITS(0, 1))) { 870 switch(__SHIFTOUT(class, __BITS(0, 1))) {
872 case 0: print_class0(); break; 871 case 0: print_class0(); break;
873 default: break; 872 default: break;
874 } 873 }
875 874
876 tag(NULL); 875 tag(NULL);
877} 876}
878 877
879void 878static void
880print_class0(void) 879print_class0(void)
881{ 880{
882 881
883 switch (__SHIFTOUT(class, __BITS(8, 12))) { 882 switch (__SHIFTOUT(class, __BITS(8, 12))) {
884 case 1: /* Computer */ 883 case 1: /* Computer */
885 switch (__SHIFTOUT(class, __BITS(2, 7))) { 884 switch (__SHIFTOUT(class, __BITS(2, 7))) {
886 case 1: tag("Desktop workstation"); break; 885 case 1: tag("Desktop workstation"); break;
887 case 2: tag("Server-class computer"); break; 886 case 2: tag("Server-class computer"); break;
888 case 3: tag("Laptop"); break; 887 case 3: tag("Laptop"); break;
889 case 4: tag("Handheld PC/PDA"); break; 888 case 4: tag("Handheld PC/PDA"); break;
890 case 5: tag("Palm Sized PC/PDA"); break; 889 case 5: tag("Palm Sized PC/PDA"); break;
891 case 6: tag("Wearable computer"); break; 890 case 6: tag("Wearable computer"); break;
892 default: tag("Computer"); break; 891 default: tag("Computer"); break;
@@ -1003,27 +1002,27 @@ print_class0(void) @@ -1003,27 +1002,27 @@ print_class0(void)
1003 } 1002 }
1004 1003
1005 if (class & __BIT(13)) tag("<Limited Discoverable>"); 1004 if (class & __BIT(13)) tag("<Limited Discoverable>");
1006 if (class & __BIT(16)) tag("<Positioning>"); 1005 if (class & __BIT(16)) tag("<Positioning>");
1007 if (class & __BIT(17)) tag("<Networking>"); 1006 if (class & __BIT(17)) tag("<Networking>");
1008 if (class & __BIT(18)) tag("<Rendering>"); 1007 if (class & __BIT(18)) tag("<Rendering>");
1009 if (class & __BIT(19)) tag("<Capturing>"); 1008 if (class & __BIT(19)) tag("<Capturing>");
1010 if (class & __BIT(20)) tag("<Object Transfer>"); 1009 if (class & __BIT(20)) tag("<Object Transfer>");
1011 if (class & __BIT(21)) tag("<Audio>"); 1010 if (class & __BIT(21)) tag("<Audio>");
1012 if (class & __BIT(22)) tag("<Telephony>"); 1011 if (class & __BIT(22)) tag("<Telephony>");
1013 if (class & __BIT(23)) tag("<Information>"); 1012 if (class & __BIT(23)) tag("<Information>");
1014} 1013}
1015 1014
1016void 1015static void
1017print_voice(int level) 1016print_voice(int level)
1018{ 1017{
1019 printf("\tvoice: [0x%4.4x]\n", voice); 1018 printf("\tvoice: [0x%4.4x]\n", voice);
1020 1019
1021 if (level == 0) 1020 if (level == 0)
1022 return; 1021 return;
1023 1022
1024 printf("\t\tInput Coding: "); 1023 printf("\t\tInput Coding: ");
1025 switch ((voice & 0x0300) >> 8) { 1024 switch ((voice & 0x0300) >> 8) {
1026 case 0x00: printf("Linear PCM [%d-bit, pos %d]", 1025 case 0x00: printf("Linear PCM [%d-bit, pos %d]",
1027 (voice & 0x0020 ? 16 : 8), 1026 (voice & 0x0020 ? 16 : 8),
1028 (voice & 0x001c) >> 2); break; 1027 (voice & 0x001c) >> 2); break;
1029 case 0x01: printf("u-Law"); break; 1028 case 0x01: printf("u-Law"); break;
@@ -1039,27 +1038,27 @@ print_voice(int level) @@ -1039,27 +1038,27 @@ print_voice(int level)
1039 } 1038 }
1040 1039
1041 printf("\n\t\tAir Coding: "); 1040 printf("\n\t\tAir Coding: ");
1042 switch (voice & 0x0003) { 1041 switch (voice & 0x0003) {
1043 case 0x00: printf("CVSD"); break; 1042 case 0x00: printf("CVSD"); break;
1044 case 0x01: printf("u-Law"); break; 1043 case 0x01: printf("u-Law"); break;
1045 case 0x02: printf("A-Law"); break; 1044 case 0x02: printf("A-Law"); break;
1046 case 0x03: printf("Transparent"); break; 1045 case 0x03: printf("Transparent"); break;
1047 } 1046 }
1048 1047
1049 printf("\n"); 1048 printf("\n");
1050} 1049}
1051 1050
1052void 1051static void
1053print_result(int num, struct bt_devinquiry *r) 1052print_result(int num, struct bt_devinquiry *r)
1054{ 1053{
1055 hci_remote_name_req_cp ncp; 1054 hci_remote_name_req_cp ncp;
1056 hci_remote_name_req_compl_ep nep; 1055 hci_remote_name_req_compl_ep nep;
1057 struct hostent *hp; 1056 struct hostent *hp;
1058 1057
1059 printf("%3d: bdaddr %s", num, bt_ntoa(&r->bdaddr, NULL)); 1058 printf("%3d: bdaddr %s", num, bt_ntoa(&r->bdaddr, NULL));
1060 1059
1061 hp = bt_gethostbyaddr((const char *)&r->bdaddr, sizeof(bdaddr_t), AF_BLUETOOTH); 1060 hp = bt_gethostbyaddr((const char *)&r->bdaddr, sizeof(bdaddr_t), AF_BLUETOOTH);
1062 if (hp != NULL) 1061 if (hp != NULL)
1063 printf(" (%s)", hp->h_name); 1062 printf(" (%s)", hp->h_name);
1064 1063
1065 printf("\n"); 1064 printf("\n");
@@ -1072,27 +1071,27 @@ print_result(int num, struct bt_devinqui @@ -1072,27 +1071,27 @@ print_result(int num, struct bt_devinqui
1072 hci_req(HCI_CMD_REMOTE_NAME_REQ, 1071 hci_req(HCI_CMD_REMOTE_NAME_REQ,
1073 HCI_EVENT_REMOTE_NAME_REQ_COMPL, 1072 HCI_EVENT_REMOTE_NAME_REQ_COMPL,
1074 &ncp, sizeof(ncp), 1073 &ncp, sizeof(ncp),
1075 &nep, sizeof(nep)); 1074 &nep, sizeof(nep));
1076 1075
1077 printf(" : name \"%s\"\n", nep.name); 1076 printf(" : name \"%s\"\n", nep.name);
1078 print_class(" : class", r->dev_class); 1077 print_class(" : class", r->dev_class);
1079 printf(" : page scan rep mode 0x%02x\n", r->pscan_rep_mode); 1078 printf(" : page scan rep mode 0x%02x\n", r->pscan_rep_mode);
1080 printf(" : clock offset %d\n", le16toh(r->clock_offset)); 1079 printf(" : clock offset %d\n", le16toh(r->clock_offset));
1081 printf(" : rssi %d\n", r->rssi); 1080 printf(" : rssi %d\n", r->rssi);
1082 printf("\n"); 1081 printf("\n");
1083} 1082}
1084 1083
1085void 1084static void
1086do_inquiry(void) 1085do_inquiry(void)
1087{ 1086{
1088 struct bt_devinquiry *result; 1087 struct bt_devinquiry *result;
1089 int i, num; 1088 int i, num;
1090 1089
1091 if (opt_inquiry == 0) 1090 if (opt_inquiry == 0)
1092 return; 1091 return;
1093 1092
1094 printf("Device Discovery from device: %s ...", btr.btr_name); 1093 printf("Device Discovery from device: %s ...", btr.btr_name);
1095 fflush(stdout); 1094 fflush(stdout);
1096 1095
1097 num = bt_devinquiry(btr.btr_name, INQUIRY_LENGTH, 1096 num = bt_devinquiry(btr.btr_name, INQUIRY_LENGTH,
1098 INQUIRY_MAX_RESPONSES, &result); 1097 INQUIRY_MAX_RESPONSES, &result);