CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
orangepi-xunlong

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: orangepi-xunlong/orangepi-build
Path: blob/next/external/cache/sources/hcitools/hcitool.c
Views: 3959
1
/*
2
*
3
* BlueZ - Bluetooth protocol stack for Linux
4
*
5
* Copyright (C) 2000-2001 Qualcomm Incorporated
6
* Copyright (C) 2002-2003 Maxim Krasnyansky <[email protected]>
7
* Copyright (C) 2002-2010 Marcel Holtmann <[email protected]>
8
*
9
*
10
* This program is free software; you can redistribute it and/or modify
11
* it under the terms of the GNU General Public License as published by
12
* the Free Software Foundation; either version 2 of the License, or
13
* (at your option) any later version.
14
*
15
* This program is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU General Public License for more details.
19
*
20
* You should have received a copy of the GNU General Public License
21
* along with this program; if not, write to the Free Software
22
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23
*
24
*/
25
26
#ifdef HAVE_CONFIG_H
27
#include <config.h>
28
#endif
29
30
#include <stdio.h>
31
#include <errno.h>
32
#include <ctype.h>
33
#include <fcntl.h>
34
#include <unistd.h>
35
#include <stdlib.h>
36
#include <string.h>
37
#include <getopt.h>
38
#include <sys/param.h>
39
#include <sys/ioctl.h>
40
#include <sys/socket.h>
41
#include <signal.h>
42
43
//#include <glib.h>
44
45
#include <bluetooth/bluetooth.h>
46
#include <bluetooth/hci.h>
47
#include <bluetooth/hci_lib.h>
48
49
/* Unofficial value, might still change */
50
#define LE_LINK 0x03
51
52
#define FLAGS_AD_TYPE 0x01
53
#define FLAGS_LIMITED_MODE_BIT 0x01
54
#define FLAGS_GENERAL_MODE_BIT 0x02
55
56
#define EIR_FLAGS 0x01 /* flags */
57
#define EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */
58
#define EIR_UUID16_ALL 0x03 /* 16-bit UUID, all listed */
59
#define EIR_UUID32_SOME 0x04 /* 32-bit UUID, more available */
60
#define EIR_UUID32_ALL 0x05 /* 32-bit UUID, all listed */
61
#define EIR_UUID128_SOME 0x06 /* 128-bit UUID, more available */
62
#define EIR_UUID128_ALL 0x07 /* 128-bit UUID, all listed */
63
#define EIR_NAME_SHORT 0x08 /* shortened local name */
64
#define EIR_NAME_COMPLETE 0x09 /* complete local name */
65
#define EIR_TX_POWER 0x0A /* transmit power level */
66
#define EIR_DEVICE_ID 0x10 /* device ID */
67
68
#define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, NULL)) != -1)
69
70
static volatile int signal_received = 0;
71
72
static void usage(void);
73
74
static char *batocomp(const bdaddr_t *ba)
75
{
76
return NULL;
77
}
78
79
static int dev_info(int s, int dev_id, long arg)
80
{
81
struct hci_dev_info di = { .dev_id = dev_id };
82
char addr[18];
83
84
if (ioctl(s, HCIGETDEVINFO, (void *) &di))
85
return 0;
86
87
ba2str(&di.bdaddr, addr);
88
printf("\t%s\t%s\n", di.name, addr);
89
return 0;
90
}
91
92
static void helper_arg(int min_num_arg, int max_num_arg, int *argc,
93
char ***argv, const char *usage)
94
{
95
*argc -= optind;
96
/* too many arguments, but when "max_num_arg < min_num_arg" then no
97
limiting (prefer "max_num_arg=-1" to gen infinity)
98
*/
99
if ( (*argc > max_num_arg) && (max_num_arg >= min_num_arg ) ) {
100
fprintf(stderr, "%s: too many arguments (maximal: %i)\n",
101
*argv[0], max_num_arg);
102
printf("%s", usage);
103
exit(1);
104
}
105
106
/* print usage */
107
if (*argc < min_num_arg) {
108
fprintf(stderr, "%s: too few arguments (minimal: %i)\n",
109
*argv[0], min_num_arg);
110
printf("%s", usage);
111
exit(0);
112
}
113
114
*argv += optind;
115
}
116
117
static char *type2str(uint8_t type)
118
{
119
switch (type) {
120
case SCO_LINK:
121
return "SCO";
122
case ACL_LINK:
123
return "ACL";
124
case ESCO_LINK:
125
return "eSCO";
126
case LE_LINK:
127
return "LE";
128
default:
129
return "Unknown";
130
}
131
}
132
133
static int conn_list(int s, int dev_id, long arg)
134
{
135
struct hci_conn_list_req *cl;
136
struct hci_conn_info *ci;
137
int id = arg;
138
int i;
139
140
if (id != -1 && dev_id != id)
141
return 0;
142
143
if (!(cl = malloc(10 * sizeof(*ci) + sizeof(*cl)))) {
144
perror("Can't allocate memory");
145
exit(1);
146
}
147
cl->dev_id = dev_id;
148
cl->conn_num = 10;
149
ci = cl->conn_info;
150
151
if (ioctl(s, HCIGETCONNLIST, (void *) cl)) {
152
perror("Can't get connection list");
153
exit(1);
154
}
155
156
for (i = 0; i < cl->conn_num; i++, ci++) {
157
char addr[18];
158
char *str;
159
ba2str(&ci->bdaddr, addr);
160
str = hci_lmtostr(ci->link_mode);
161
printf("\t%s %s %s handle %d state %d lm %s\n",
162
ci->out ? "<" : ">", type2str(ci->type),
163
addr, ci->handle, ci->state, str);
164
bt_free(str);
165
}
166
167
free(cl);
168
return 0;
169
}
170
171
static int find_conn(int s, int dev_id, long arg)
172
{
173
struct hci_conn_list_req *cl;
174
struct hci_conn_info *ci;
175
int i;
176
177
if (!(cl = malloc(10 * sizeof(*ci) + sizeof(*cl)))) {
178
perror("Can't allocate memory");
179
exit(1);
180
}
181
cl->dev_id = dev_id;
182
cl->conn_num = 10;
183
ci = cl->conn_info;
184
185
if (ioctl(s, HCIGETCONNLIST, (void *) cl)) {
186
perror("Can't get connection list");
187
exit(1);
188
}
189
190
for (i = 0; i < cl->conn_num; i++, ci++)
191
if (!bacmp((bdaddr_t *) arg, &ci->bdaddr)) {
192
free(cl);
193
return 1;
194
}
195
196
free(cl);
197
return 0;
198
}
199
200
static void hex_dump(char *pref, int width, unsigned char *buf, int len)
201
{
202
register int i,n;
203
204
for (i = 0, n = 1; i < len; i++, n++) {
205
if (n == 1)
206
printf("%s", pref);
207
printf("%2.2X ", buf[i]);
208
if (n == width) {
209
printf("\n");
210
n = 0;
211
}
212
}
213
if (i && n!=1)
214
printf("\n");
215
}
216
217
static char *get_minor_device_name(int major, int minor)
218
{
219
switch (major) {
220
case 0: /* misc */
221
return "";
222
case 1: /* computer */
223
switch (minor) {
224
case 0:
225
return "Uncategorized";
226
case 1:
227
return "Desktop workstation";
228
case 2:
229
return "Server";
230
case 3:
231
return "Laptop";
232
case 4:
233
return "Handheld";
234
case 5:
235
return "Palm";
236
case 6:
237
return "Wearable";
238
}
239
break;
240
case 2: /* phone */
241
switch (minor) {
242
case 0:
243
return "Uncategorized";
244
case 1:
245
return "Cellular";
246
case 2:
247
return "Cordless";
248
case 3:
249
return "Smart phone";
250
case 4:
251
return "Wired modem or voice gateway";
252
case 5:
253
return "Common ISDN Access";
254
case 6:
255
return "Sim Card Reader";
256
}
257
break;
258
case 3: /* lan access */
259
if (minor == 0)
260
return "Uncategorized";
261
switch (minor / 8) {
262
case 0:
263
return "Fully available";
264
case 1:
265
return "1-17% utilized";
266
case 2:
267
return "17-33% utilized";
268
case 3:
269
return "33-50% utilized";
270
case 4:
271
return "50-67% utilized";
272
case 5:
273
return "67-83% utilized";
274
case 6:
275
return "83-99% utilized";
276
case 7:
277
return "No service available";
278
}
279
break;
280
case 4: /* audio/video */
281
switch (minor) {
282
case 0:
283
return "Uncategorized";
284
case 1:
285
return "Device conforms to the Headset profile";
286
case 2:
287
return "Hands-free";
288
/* 3 is reserved */
289
case 4:
290
return "Microphone";
291
case 5:
292
return "Loudspeaker";
293
case 6:
294
return "Headphones";
295
case 7:
296
return "Portable Audio";
297
case 8:
298
return "Car Audio";
299
case 9:
300
return "Set-top box";
301
case 10:
302
return "HiFi Audio Device";
303
case 11:
304
return "VCR";
305
case 12:
306
return "Video Camera";
307
case 13:
308
return "Camcorder";
309
case 14:
310
return "Video Monitor";
311
case 15:
312
return "Video Display and Loudspeaker";
313
case 16:
314
return "Video Conferencing";
315
/* 17 is reserved */
316
case 18:
317
return "Gaming/Toy";
318
}
319
break;
320
case 5: /* peripheral */ {
321
static char cls_str[48]; cls_str[0] = 0;
322
323
switch (minor & 48) {
324
case 16:
325
strncpy(cls_str, "Keyboard", sizeof(cls_str));
326
break;
327
case 32:
328
strncpy(cls_str, "Pointing device", sizeof(cls_str));
329
break;
330
case 48:
331
strncpy(cls_str, "Combo keyboard/pointing device", sizeof(cls_str));
332
break;
333
}
334
if ((minor & 15) && (strlen(cls_str) > 0))
335
strcat(cls_str, "/");
336
337
switch (minor & 15) {
338
case 0:
339
break;
340
case 1:
341
strncat(cls_str, "Joystick", sizeof(cls_str) - strlen(cls_str));
342
break;
343
case 2:
344
strncat(cls_str, "Gamepad", sizeof(cls_str) - strlen(cls_str));
345
break;
346
case 3:
347
strncat(cls_str, "Remote control", sizeof(cls_str) - strlen(cls_str));
348
break;
349
case 4:
350
strncat(cls_str, "Sensing device", sizeof(cls_str) - strlen(cls_str));
351
break;
352
case 5:
353
strncat(cls_str, "Digitizer tablet", sizeof(cls_str) - strlen(cls_str));
354
break;
355
case 6:
356
strncat(cls_str, "Card reader", sizeof(cls_str) - strlen(cls_str));
357
break;
358
default:
359
strncat(cls_str, "(reserved)", sizeof(cls_str) - strlen(cls_str));
360
break;
361
}
362
if (strlen(cls_str) > 0)
363
return cls_str;
364
}
365
case 6: /* imaging */
366
if (minor & 4)
367
return "Display";
368
if (minor & 8)
369
return "Camera";
370
if (minor & 16)
371
return "Scanner";
372
if (minor & 32)
373
return "Printer";
374
break;
375
case 7: /* wearable */
376
switch (minor) {
377
case 1:
378
return "Wrist Watch";
379
case 2:
380
return "Pager";
381
case 3:
382
return "Jacket";
383
case 4:
384
return "Helmet";
385
case 5:
386
return "Glasses";
387
}
388
break;
389
case 8: /* toy */
390
switch (minor) {
391
case 1:
392
return "Robot";
393
case 2:
394
return "Vehicle";
395
case 3:
396
return "Doll / Action Figure";
397
case 4:
398
return "Controller";
399
case 5:
400
return "Game";
401
}
402
break;
403
case 63: /* uncategorised */
404
return "";
405
}
406
return "Unknown (reserved) minor device class";
407
}
408
409
static char *major_classes[] = {
410
"Miscellaneous", "Computer", "Phone", "LAN Access",
411
"Audio/Video", "Peripheral", "Imaging", "Uncategorized"
412
};
413
414
static char *get_device_name(const bdaddr_t *local, const bdaddr_t *peer)
415
{
416
#if 0
417
char filename[PATH_MAX + 1];
418
char local_addr[18], peer_addr[18];
419
GKeyFile *key_file;
420
char *str = NULL;
421
int len;
422
423
ba2str(local, local_addr);
424
ba2str(peer, peer_addr);
425
426
snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", local_addr,
427
peer_addr);
428
filename[PATH_MAX] = '\0';
429
key_file = g_key_file_new();
430
431
if (g_key_file_load_from_file(key_file, filename, 0, NULL)) {
432
str = g_key_file_get_string(key_file, "General", "Name", NULL);
433
if (str) {
434
len = strlen(str);
435
if (len > HCI_MAX_NAME_LENGTH)
436
str[HCI_MAX_NAME_LENGTH] = '\0';
437
}
438
}
439
440
g_key_file_free(key_file);
441
442
return str;
443
#endif
444
return NULL;
445
}
446
447
/* Display local devices */
448
449
static struct option dev_options[] = {
450
{ "help", 0, 0, 'h' },
451
{0, 0, 0, 0 }
452
};
453
454
static const char *dev_help =
455
"Usage:\n"
456
"\tdev\n";
457
458
static void cmd_dev(int dev_id, int argc, char **argv)
459
{
460
int opt;
461
462
for_each_opt(opt, dev_options, NULL) {
463
switch (opt) {
464
default:
465
printf("%s", dev_help);
466
return;
467
}
468
}
469
helper_arg(0, 0, &argc, &argv, dev_help);
470
471
printf("Devices:\n");
472
473
hci_for_each_dev(HCI_UP, dev_info, 0);
474
}
475
476
/* Inquiry */
477
478
static struct option inq_options[] = {
479
{ "help", 0, 0, 'h' },
480
{ "length", 1, 0, 'l' },
481
{ "numrsp", 1, 0, 'n' },
482
{ "iac", 1, 0, 'i' },
483
{ "flush", 0, 0, 'f' },
484
{ 0, 0, 0, 0 }
485
};
486
487
static const char *inq_help =
488
"Usage:\n"
489
"\tinq [--length=N] maximum inquiry duration in 1.28 s units\n"
490
"\t [--numrsp=N] specify maximum number of inquiry responses\n"
491
"\t [--iac=lap] specify the inquiry access code\n"
492
"\t [--flush] flush the inquiry cache\n";
493
494
static void cmd_inq(int dev_id, int argc, char **argv)
495
{
496
inquiry_info *info = NULL;
497
uint8_t lap[3] = { 0x33, 0x8b, 0x9e };
498
int num_rsp, length, flags;
499
char addr[18];
500
int i, l, opt;
501
502
length = 8; /* ~10 seconds */
503
num_rsp = 0;
504
flags = 0;
505
506
for_each_opt(opt, inq_options, NULL) {
507
switch (opt) {
508
case 'l':
509
length = atoi(optarg);
510
break;
511
512
case 'n':
513
num_rsp = atoi(optarg);
514
break;
515
516
case 'i':
517
l = strtoul(optarg, 0, 16);
518
if (!strcasecmp(optarg, "giac")) {
519
l = 0x9e8b33;
520
} else if (!strcasecmp(optarg, "liac")) {
521
l = 0x9e8b00;
522
} if (l < 0x9e8b00 || l > 0x9e8b3f) {
523
printf("Invalid access code 0x%x\n", l);
524
exit(1);
525
}
526
lap[0] = (l & 0xff);
527
lap[1] = (l >> 8) & 0xff;
528
lap[2] = (l >> 16) & 0xff;
529
break;
530
531
case 'f':
532
flags |= IREQ_CACHE_FLUSH;
533
break;
534
535
default:
536
printf("%s", inq_help);
537
return;
538
}
539
}
540
helper_arg(0, 0, &argc, &argv, inq_help);
541
542
printf("Inquiring ...\n");
543
544
num_rsp = hci_inquiry(dev_id, length, num_rsp, lap, &info, flags);
545
if (num_rsp < 0) {
546
perror("Inquiry failed.");
547
exit(1);
548
}
549
550
for (i = 0; i < num_rsp; i++) {
551
ba2str(&(info+i)->bdaddr, addr);
552
printf("\t%s\tclock offset: 0x%4.4x\tclass: 0x%2.2x%2.2x%2.2x\n",
553
addr, btohs((info+i)->clock_offset),
554
(info+i)->dev_class[2],
555
(info+i)->dev_class[1],
556
(info+i)->dev_class[0]);
557
}
558
559
bt_free(info);
560
}
561
562
/* Device scanning */
563
564
static struct option scan_options[] = {
565
{ "help", 0, 0, 'h' },
566
{ "length", 1, 0, 'l' },
567
{ "numrsp", 1, 0, 'n' },
568
{ "iac", 1, 0, 'i' },
569
{ "flush", 0, 0, 'f' },
570
{ "refresh", 0, 0, 'r' },
571
{ "class", 0, 0, 'C' },
572
{ "info", 0, 0, 'I' },
573
{ "oui", 0, 0, 'O' },
574
{ "all", 0, 0, 'A' },
575
{ "ext", 0, 0, 'A' },
576
{ 0, 0, 0, 0 }
577
};
578
579
static const char *scan_help =
580
"Usage:\n"
581
"\tscan [--length=N] [--numrsp=N] [--iac=lap] [--flush] [--class] [--info] [--oui] [--refresh]\n";
582
583
static void cmd_scan(int dev_id, int argc, char **argv)
584
{
585
inquiry_info *info = NULL;
586
uint8_t lap[3] = { 0x33, 0x8b, 0x9e };
587
int num_rsp, length, flags;
588
uint8_t cls[3], features[8];
589
char addr[18], name[249], *comp, *tmp;
590
struct hci_version version;
591
struct hci_dev_info di;
592
struct hci_conn_info_req *cr;
593
int refresh = 0, extcls = 0, extinf = 0, extoui = 0;
594
int i, n, l, opt, dd, cc, nc;
595
596
length = 8; /* ~10 seconds */
597
num_rsp = 0;
598
flags = 0;
599
600
for_each_opt(opt, scan_options, NULL) {
601
switch (opt) {
602
case 'l':
603
length = atoi(optarg);
604
break;
605
606
case 'n':
607
num_rsp = atoi(optarg);
608
break;
609
610
case 'i':
611
l = strtoul(optarg, 0, 16);
612
if (!strcasecmp(optarg, "giac")) {
613
l = 0x9e8b33;
614
} else if (!strcasecmp(optarg, "liac")) {
615
l = 0x9e8b00;
616
} else if (l < 0x9e8b00 || l > 0x9e8b3f) {
617
printf("Invalid access code 0x%x\n", l);
618
exit(1);
619
}
620
lap[0] = (l & 0xff);
621
lap[1] = (l >> 8) & 0xff;
622
lap[2] = (l >> 16) & 0xff;
623
break;
624
625
case 'f':
626
flags |= IREQ_CACHE_FLUSH;
627
break;
628
629
case 'r':
630
refresh = 1;
631
break;
632
633
case 'C':
634
extcls = 1;
635
break;
636
637
case 'I':
638
extinf = 1;
639
break;
640
641
case 'O':
642
extoui = 1;
643
break;
644
645
case 'A':
646
extcls = 1;
647
extinf = 1;
648
extoui = 1;
649
break;
650
651
default:
652
printf("%s", scan_help);
653
return;
654
}
655
}
656
helper_arg(0, 0, &argc, &argv, scan_help);
657
658
if (dev_id < 0) {
659
dev_id = hci_get_route(NULL);
660
if (dev_id < 0) {
661
perror("Device is not available");
662
exit(1);
663
}
664
}
665
666
if (hci_devinfo(dev_id, &di) < 0) {
667
perror("Can't get device info");
668
exit(1);
669
}
670
671
printf("Scanning ...\n");
672
num_rsp = hci_inquiry(dev_id, length, num_rsp, lap, &info, flags);
673
if (num_rsp < 0) {
674
perror("Inquiry failed");
675
exit(1);
676
}
677
678
dd = hci_open_dev(dev_id);
679
if (dd < 0) {
680
perror("HCI device open failed");
681
free(info);
682
exit(1);
683
}
684
685
if (extcls || extinf || extoui)
686
printf("\n");
687
688
for (i = 0; i < num_rsp; i++) {
689
uint16_t handle = 0;
690
691
if (!refresh) {
692
memset(name, 0, sizeof(name));
693
tmp = get_device_name(&di.bdaddr, &(info+i)->bdaddr);
694
if (tmp) {
695
strncpy(name, tmp, 249);
696
free(tmp);
697
nc = 1;
698
} else
699
nc = 0;
700
} else
701
nc = 0;
702
703
if (!extcls && !extinf && !extoui) {
704
ba2str(&(info+i)->bdaddr, addr);
705
706
if (nc) {
707
printf("\t%s\t%s\n", addr, name);
708
continue;
709
}
710
711
if (hci_read_remote_name_with_clock_offset(dd,
712
&(info+i)->bdaddr,
713
(info+i)->pscan_rep_mode,
714
(info+i)->clock_offset | 0x8000,
715
sizeof(name), name, 100000) < 0)
716
strcpy(name, "n/a");
717
718
for (n = 0; n < 248 && name[n]; n++) {
719
if ((unsigned char) name[i] < 32 || name[i] == 127)
720
name[i] = '.';
721
}
722
723
name[248] = '\0';
724
725
printf("\t%s\t%s\n", addr, name);
726
continue;
727
}
728
729
ba2str(&(info+i)->bdaddr, addr);
730
printf("BD Address:\t%s [mode %d, clkoffset 0x%4.4x]\n", addr,
731
(info+i)->pscan_rep_mode, btohs((info+i)->clock_offset));
732
733
if (extoui) {
734
comp = batocomp(&(info+i)->bdaddr);
735
if (comp) {
736
char oui[9];
737
ba2oui(&(info+i)->bdaddr, oui);
738
printf("OUI company:\t%s (%s)\n", comp, oui);
739
free(comp);
740
}
741
}
742
743
cc = 0;
744
745
if (extinf) {
746
cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
747
if (cr) {
748
bacpy(&cr->bdaddr, &(info+i)->bdaddr);
749
cr->type = ACL_LINK;
750
if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
751
handle = 0;
752
cc = 1;
753
} else {
754
handle = htobs(cr->conn_info->handle);
755
cc = 0;
756
}
757
free(cr);
758
}
759
760
if (cc) {
761
if (hci_create_connection(dd, &(info+i)->bdaddr,
762
htobs(di.pkt_type & ACL_PTYPE_MASK),
763
(info+i)->clock_offset | 0x8000,
764
0x01, &handle, 25000) < 0) {
765
handle = 0;
766
cc = 0;
767
}
768
}
769
}
770
771
if (handle > 0 || !nc) {
772
if (hci_read_remote_name_with_clock_offset(dd,
773
&(info+i)->bdaddr,
774
(info+i)->pscan_rep_mode,
775
(info+i)->clock_offset | 0x8000,
776
sizeof(name), name, 100000) < 0) {
777
if (!nc)
778
strcpy(name, "n/a");
779
} else {
780
for (n = 0; n < 248 && name[n]; n++) {
781
if ((unsigned char) name[i] < 32 || name[i] == 127)
782
name[i] = '.';
783
}
784
785
name[248] = '\0';
786
nc = 0;
787
}
788
}
789
790
if (strlen(name) > 0)
791
printf("Device name:\t%s%s\n", name, nc ? " [cached]" : "");
792
793
if (extcls) {
794
memcpy(cls, (info+i)->dev_class, 3);
795
printf("Device class:\t");
796
if ((cls[1] & 0x1f) > sizeof(major_classes) / sizeof(char *))
797
printf("Invalid");
798
else
799
printf("%s, %s", major_classes[cls[1] & 0x1f],
800
get_minor_device_name(cls[1] & 0x1f, cls[0] >> 2));
801
printf(" (0x%2.2x%2.2x%2.2x)\n", cls[2], cls[1], cls[0]);
802
}
803
804
if (extinf && handle > 0) {
805
if (hci_read_remote_version(dd, handle, &version, 20000) == 0) {
806
char *ver = lmp_vertostr(version.lmp_ver);
807
printf("Manufacturer:\t%s (%d)\n",
808
bt_compidtostr(version.manufacturer),
809
version.manufacturer);
810
printf("LMP version:\t%s (0x%x) [subver 0x%x]\n",
811
ver ? ver : "n/a",
812
version.lmp_ver, version.lmp_subver);
813
if (ver)
814
bt_free(ver);
815
}
816
817
if (hci_read_remote_features(dd, handle, features, 20000) == 0) {
818
char *tmp = lmp_featurestostr(features, "\t\t", 63);
819
printf("LMP features:\t0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x"
820
" 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n",
821
features[0], features[1],
822
features[2], features[3],
823
features[4], features[5],
824
features[6], features[7]);
825
printf("%s\n", tmp);
826
bt_free(tmp);
827
}
828
829
if (cc) {
830
usleep(10000);
831
hci_disconnect(dd, handle, HCI_OE_USER_ENDED_CONNECTION, 10000);
832
}
833
}
834
835
printf("\n");
836
}
837
838
bt_free(info);
839
840
hci_close_dev(dd);
841
}
842
843
/* Remote name */
844
845
static struct option name_options[] = {
846
{ "help", 0, 0, 'h' },
847
{ 0, 0, 0, 0 }
848
};
849
850
static const char *name_help =
851
"Usage:\n"
852
"\tname <bdaddr>\n";
853
854
static void cmd_name(int dev_id, int argc, char **argv)
855
{
856
bdaddr_t bdaddr;
857
char name[248];
858
int opt, dd;
859
860
for_each_opt(opt, name_options, NULL) {
861
switch (opt) {
862
default:
863
printf("%s", name_help);
864
return;
865
}
866
}
867
helper_arg(1, 1, &argc, &argv, name_help);
868
869
str2ba(argv[0], &bdaddr);
870
871
if (dev_id < 0) {
872
dev_id = hci_get_route(&bdaddr);
873
if (dev_id < 0) {
874
fprintf(stderr, "Device is not available.\n");
875
exit(1);
876
}
877
}
878
879
dd = hci_open_dev(dev_id);
880
if (dd < 0) {
881
perror("HCI device open failed");
882
exit(1);
883
}
884
885
if (hci_read_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0)
886
printf("%s\n", name);
887
888
hci_close_dev(dd);
889
}
890
891
/* Info about remote device */
892
893
static struct option info_options[] = {
894
{ "help", 0, 0, 'h' },
895
{ 0, 0, 0, 0 }
896
};
897
898
static const char *info_help =
899
"Usage:\n"
900
"\tinfo <bdaddr>\n";
901
902
static void cmd_info(int dev_id, int argc, char **argv)
903
{
904
bdaddr_t bdaddr;
905
uint16_t handle;
906
uint8_t features[8], max_page = 0;
907
char name[249], *comp, *tmp;
908
struct hci_version version;
909
struct hci_dev_info di;
910
struct hci_conn_info_req *cr;
911
int i, opt, dd, cc = 0;
912
913
for_each_opt(opt, info_options, NULL) {
914
switch (opt) {
915
default:
916
printf("%s", info_help);
917
return;
918
}
919
}
920
helper_arg(1, 1, &argc, &argv, info_help);
921
922
str2ba(argv[0], &bdaddr);
923
924
if (dev_id < 0)
925
dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
926
927
if (dev_id < 0)
928
dev_id = hci_get_route(&bdaddr);
929
930
if (dev_id < 0) {
931
fprintf(stderr, "Device is not available or not connected.\n");
932
exit(1);
933
}
934
935
if (hci_devinfo(dev_id, &di) < 0) {
936
perror("Can't get device info");
937
exit(1);
938
}
939
940
printf("Requesting information ...\n");
941
942
dd = hci_open_dev(dev_id);
943
if (dd < 0) {
944
perror("HCI device open failed");
945
exit(1);
946
}
947
948
cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
949
if (!cr) {
950
perror("Can't get connection info");
951
close(dd);
952
exit(1);
953
}
954
955
bacpy(&cr->bdaddr, &bdaddr);
956
cr->type = ACL_LINK;
957
if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
958
if (hci_create_connection(dd, &bdaddr,
959
htobs(di.pkt_type & ACL_PTYPE_MASK),
960
0, 0x01, &handle, 25000) < 0) {
961
perror("Can't create connection");
962
close(dd);
963
exit(1);
964
}
965
sleep(1);
966
cc = 1;
967
} else
968
handle = htobs(cr->conn_info->handle);
969
970
printf("\tBD Address: %s\n", argv[0]);
971
972
comp = batocomp(&bdaddr);
973
if (comp) {
974
char oui[9];
975
ba2oui(&bdaddr, oui);
976
printf("\tOUI Company: %s (%s)\n", comp, oui);
977
free(comp);
978
}
979
980
if (hci_read_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0)
981
printf("\tDevice Name: %s\n", name);
982
983
if (hci_read_remote_version(dd, handle, &version, 20000) == 0) {
984
char *ver = lmp_vertostr(version.lmp_ver);
985
printf("\tLMP Version: %s (0x%x) LMP Subversion: 0x%x\n"
986
"\tManufacturer: %s (%d)\n",
987
ver ? ver : "n/a",
988
version.lmp_ver,
989
version.lmp_subver,
990
bt_compidtostr(version.manufacturer),
991
version.manufacturer);
992
if (ver)
993
bt_free(ver);
994
}
995
996
memset(features, 0, sizeof(features));
997
hci_read_remote_features(dd, handle, features, 20000);
998
999
if ((di.features[7] & LMP_EXT_FEAT) && (features[7] & LMP_EXT_FEAT))
1000
hci_read_remote_ext_features(dd, handle, 0, &max_page,
1001
features, 20000);
1002
1003
printf("\tFeatures%s: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
1004
"0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n",
1005
(max_page > 0) ? " page 0" : "",
1006
features[0], features[1], features[2], features[3],
1007
features[4], features[5], features[6], features[7]);
1008
1009
tmp = lmp_featurestostr(features, "\t\t", 63);
1010
printf("%s\n", tmp);
1011
bt_free(tmp);
1012
1013
for (i = 1; i <= max_page; i++) {
1014
if (hci_read_remote_ext_features(dd, handle, i, NULL,
1015
features, 20000) < 0)
1016
continue;
1017
1018
printf("\tFeatures page %d: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
1019
"0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", i,
1020
features[0], features[1], features[2], features[3],
1021
features[4], features[5], features[6], features[7]);
1022
}
1023
1024
if (cc) {
1025
usleep(10000);
1026
hci_disconnect(dd, handle, HCI_OE_USER_ENDED_CONNECTION, 10000);
1027
}
1028
1029
hci_close_dev(dd);
1030
}
1031
1032
/* Start periodic inquiry */
1033
1034
static struct option spinq_options[] = {
1035
{ "help", 0, 0, 'h' },
1036
{ 0, 0, 0, 0 }
1037
};
1038
1039
static const char *spinq_help =
1040
"Usage:\n"
1041
"\tspinq\n";
1042
1043
static void cmd_spinq(int dev_id, int argc, char **argv)
1044
{
1045
uint8_t lap[3] = { 0x33, 0x8b, 0x9e };
1046
struct hci_request rq;
1047
periodic_inquiry_cp cp;
1048
int opt, dd;
1049
1050
for_each_opt(opt, spinq_options, NULL) {
1051
switch (opt) {
1052
default:
1053
printf("%s", spinq_help);
1054
return;
1055
}
1056
}
1057
helper_arg(0, 0, &argc, &argv, spinq_help);
1058
1059
if (dev_id < 0)
1060
dev_id = hci_get_route(NULL);
1061
1062
dd = hci_open_dev(dev_id);
1063
if (dd < 0) {
1064
perror("Device open failed");
1065
exit(EXIT_FAILURE);
1066
}
1067
1068
memset(&cp, 0, sizeof(cp));
1069
memcpy(cp.lap, lap, 3);
1070
cp.max_period = htobs(16);
1071
cp.min_period = htobs(10);
1072
cp.length = 8;
1073
cp.num_rsp = 0;
1074
1075
memset(&rq, 0, sizeof(rq));
1076
rq.ogf = OGF_LINK_CTL;
1077
rq.ocf = OCF_PERIODIC_INQUIRY;
1078
rq.cparam = &cp;
1079
rq.clen = PERIODIC_INQUIRY_CP_SIZE;
1080
1081
if (hci_send_req(dd, &rq, 100) < 0) {
1082
perror("Periodic inquiry failed");
1083
exit(EXIT_FAILURE);
1084
}
1085
1086
hci_close_dev(dd);
1087
}
1088
1089
/* Exit periodic inquiry */
1090
1091
static struct option epinq_options[] = {
1092
{ "help", 0, 0, 'h' },
1093
{ 0, 0, 0, 0 }
1094
};
1095
1096
static const char *epinq_help =
1097
"Usage:\n"
1098
"\tepinq\n";
1099
1100
static void cmd_epinq(int dev_id, int argc, char **argv)
1101
{
1102
int opt, dd;
1103
1104
for_each_opt(opt, epinq_options, NULL) {
1105
switch (opt) {
1106
default:
1107
printf("%s", epinq_help);
1108
return;
1109
}
1110
}
1111
helper_arg(0, 0, &argc, &argv, epinq_help);
1112
1113
if (dev_id < 0)
1114
dev_id = hci_get_route(NULL);
1115
1116
dd = hci_open_dev(dev_id);
1117
if (dd < 0) {
1118
perror("Device open failed");
1119
exit(EXIT_FAILURE);
1120
}
1121
1122
if (hci_send_cmd(dd, OGF_LINK_CTL,
1123
OCF_EXIT_PERIODIC_INQUIRY, 0, NULL) < 0) {
1124
perror("Exit periodic inquiry failed");
1125
exit(EXIT_FAILURE);
1126
}
1127
1128
hci_close_dev(dd);
1129
}
1130
1131
/* Send arbitrary HCI commands */
1132
1133
static struct option cmd_options[] = {
1134
{ "help", 0, 0, 'h' },
1135
{ 0, 0, 0, 0 }
1136
};
1137
1138
static const char *cmd_help =
1139
"Usage:\n"
1140
"\tcmd <ogf> <ocf> [parameters]\n"
1141
"Example:\n"
1142
"\tcmd 0x03 0x0013 0x41 0x42 0x43 0x44\n";
1143
1144
static void cmd_cmd(int dev_id, int argc, char **argv)
1145
{
1146
unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr = buf;
1147
struct hci_filter flt;
1148
hci_event_hdr *hdr;
1149
int i, opt, len, dd;
1150
uint16_t ocf;
1151
uint8_t ogf;
1152
1153
for_each_opt(opt, cmd_options, NULL) {
1154
switch (opt) {
1155
default:
1156
printf("%s", cmd_help);
1157
return;
1158
}
1159
}
1160
helper_arg(2, -1, &argc, &argv, cmd_help);
1161
1162
if (dev_id < 0)
1163
dev_id = hci_get_route(NULL);
1164
1165
errno = 0;
1166
ogf = strtol(argv[0], NULL, 16);
1167
ocf = strtol(argv[1], NULL, 16);
1168
if (errno == ERANGE || (ogf > 0x3f) || (ocf > 0x3ff)) {
1169
printf("%s", cmd_help);
1170
return;
1171
}
1172
1173
for (i = 2, len = 0; i < argc && len < (int) sizeof(buf); i++, len++)
1174
*ptr++ = (uint8_t) strtol(argv[i], NULL, 16);
1175
1176
dd = hci_open_dev(dev_id);
1177
if (dd < 0) {
1178
perror("Device open failed");
1179
exit(EXIT_FAILURE);
1180
}
1181
1182
/* Setup filter */
1183
hci_filter_clear(&flt);
1184
hci_filter_set_ptype(HCI_EVENT_PKT, &flt);
1185
hci_filter_all_events(&flt);
1186
if (setsockopt(dd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {
1187
perror("HCI filter setup failed");
1188
exit(EXIT_FAILURE);
1189
}
1190
1191
printf("< HCI Command: ogf 0x%02x, ocf 0x%04x, plen %d\n", ogf, ocf, len);
1192
hex_dump(" ", 20, buf, len); fflush(stdout);
1193
1194
if (hci_send_cmd(dd, ogf, ocf, len, buf) < 0) {
1195
perror("Send failed");
1196
exit(EXIT_FAILURE);
1197
}
1198
1199
len = read(dd, buf, sizeof(buf));
1200
if (len < 0) {
1201
perror("Read failed");
1202
exit(EXIT_FAILURE);
1203
}
1204
1205
hdr = (void *)(buf + 1);
1206
ptr = buf + (1 + HCI_EVENT_HDR_SIZE);
1207
len -= (1 + HCI_EVENT_HDR_SIZE);
1208
1209
printf("> HCI Event: 0x%02x plen %d\n", hdr->evt, hdr->plen);
1210
hex_dump(" ", 20, ptr, len); fflush(stdout);
1211
1212
hci_close_dev(dd);
1213
}
1214
1215
/* Display active connections */
1216
1217
static struct option con_options[] = {
1218
{ "help", 0, 0, 'h' },
1219
{ 0, 0, 0, 0 }
1220
};
1221
1222
static const char *con_help =
1223
"Usage:\n"
1224
"\tcon\n";
1225
1226
static void cmd_con(int dev_id, int argc, char **argv)
1227
{
1228
int opt;
1229
1230
for_each_opt(opt, con_options, NULL) {
1231
switch (opt) {
1232
default:
1233
printf("%s", con_help);
1234
return;
1235
}
1236
}
1237
helper_arg(0, 0, &argc, &argv, con_help);
1238
1239
printf("Connections:\n");
1240
1241
hci_for_each_dev(HCI_UP, conn_list, dev_id);
1242
}
1243
1244
/* Create connection */
1245
1246
static struct option cc_options[] = {
1247
{ "help", 0, 0, 'h' },
1248
{ "role", 1, 0, 'r' },
1249
{ "ptype", 1, 0, 'p' },
1250
{ 0, 0, 0, 0 }
1251
};
1252
1253
static const char *cc_help =
1254
"Usage:\n"
1255
"\tcc [--role=m|s] [--ptype=pkt_types] <bdaddr>\n"
1256
"Example:\n"
1257
"\tcc --ptype=dm1,dh3,dh5 01:02:03:04:05:06\n"
1258
"\tcc --role=m 01:02:03:04:05:06\n";
1259
1260
static void cmd_cc(int dev_id, int argc, char **argv)
1261
{
1262
bdaddr_t bdaddr;
1263
uint16_t handle;
1264
uint8_t role;
1265
unsigned int ptype;
1266
int dd, opt;
1267
1268
role = 0x01;
1269
ptype = HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5;
1270
1271
for_each_opt(opt, cc_options, NULL) {
1272
switch (opt) {
1273
case 'p':
1274
hci_strtoptype(optarg, &ptype);
1275
break;
1276
1277
case 'r':
1278
role = optarg[0] == 'm' ? 0 : 1;
1279
break;
1280
1281
default:
1282
printf("%s", cc_help);
1283
return;
1284
}
1285
}
1286
helper_arg(1, 1, &argc, &argv, cc_help);
1287
1288
str2ba(argv[0], &bdaddr);
1289
1290
if (dev_id < 0) {
1291
dev_id = hci_get_route(&bdaddr);
1292
if (dev_id < 0) {
1293
fprintf(stderr, "Device is not available.\n");
1294
exit(1);
1295
}
1296
}
1297
1298
dd = hci_open_dev(dev_id);
1299
if (dd < 0) {
1300
perror("HCI device open failed");
1301
exit(1);
1302
}
1303
1304
if (hci_create_connection(dd, &bdaddr, htobs(ptype),
1305
htobs(0x0000), role, &handle, 25000) < 0)
1306
perror("Can't create connection");
1307
1308
hci_close_dev(dd);
1309
}
1310
1311
/* Close connection */
1312
1313
static struct option dc_options[] = {
1314
{ "help", 0, 0, 'h' },
1315
{ 0, 0, 0, 0 }
1316
};
1317
1318
static const char *dc_help =
1319
"Usage:\n"
1320
"\tdc <bdaddr> [reason]\n";
1321
1322
static void cmd_dc(int dev_id, int argc, char **argv)
1323
{
1324
struct hci_conn_info_req *cr;
1325
bdaddr_t bdaddr;
1326
uint8_t reason;
1327
int opt, dd;
1328
1329
for_each_opt(opt, dc_options, NULL) {
1330
switch (opt) {
1331
default:
1332
printf("%s", dc_help);
1333
return;
1334
}
1335
}
1336
helper_arg(1, 2, &argc, &argv, dc_help);
1337
1338
str2ba(argv[0], &bdaddr);
1339
reason = (argc > 1) ? atoi(argv[1]) : HCI_OE_USER_ENDED_CONNECTION;
1340
1341
if (dev_id < 0) {
1342
dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
1343
if (dev_id < 0) {
1344
fprintf(stderr, "Not connected.\n");
1345
exit(1);
1346
}
1347
}
1348
1349
dd = hci_open_dev(dev_id);
1350
if (dd < 0) {
1351
perror("HCI device open failed");
1352
exit(1);
1353
}
1354
1355
cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
1356
if (!cr) {
1357
perror("Can't allocate memory");
1358
exit(1);
1359
}
1360
1361
bacpy(&cr->bdaddr, &bdaddr);
1362
cr->type = ACL_LINK;
1363
if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
1364
perror("Get connection info failed");
1365
exit(1);
1366
}
1367
1368
if (hci_disconnect(dd, htobs(cr->conn_info->handle),
1369
reason, 10000) < 0)
1370
perror("Disconnect failed");
1371
1372
free(cr);
1373
1374
hci_close_dev(dd);
1375
}
1376
1377
/* Role switch */
1378
1379
static struct option sr_options[] = {
1380
{ "help", 0, 0, 'h' },
1381
{ 0, 0, 0, 0 }
1382
};
1383
1384
static const char *sr_help =
1385
"Usage:\n"
1386
"\tsr <bdaddr> <role>\n";
1387
1388
static void cmd_sr(int dev_id, int argc, char **argv)
1389
{
1390
bdaddr_t bdaddr;
1391
uint8_t role;
1392
int opt, dd;
1393
1394
for_each_opt(opt, sr_options, NULL) {
1395
switch (opt) {
1396
default:
1397
printf("%s", sr_help);
1398
return;
1399
}
1400
}
1401
helper_arg(2, 2, &argc, &argv, sr_help);
1402
1403
str2ba(argv[0], &bdaddr);
1404
switch (argv[1][0]) {
1405
case 'm':
1406
role = 0;
1407
break;
1408
case 's':
1409
role = 1;
1410
break;
1411
default:
1412
role = atoi(argv[1]);
1413
break;
1414
}
1415
1416
if (dev_id < 0) {
1417
dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
1418
if (dev_id < 0) {
1419
fprintf(stderr, "Not connected.\n");
1420
exit(1);
1421
}
1422
}
1423
1424
dd = hci_open_dev(dev_id);
1425
if (dd < 0) {
1426
perror("HCI device open failed");
1427
exit(1);
1428
}
1429
1430
if (hci_switch_role(dd, &bdaddr, role, 10000) < 0) {
1431
perror("Switch role request failed");
1432
exit(1);
1433
}
1434
1435
hci_close_dev(dd);
1436
}
1437
1438
/* Read RSSI */
1439
1440
static struct option rssi_options[] = {
1441
{ "help", 0, 0, 'h' },
1442
{ 0, 0, 0, 0 }
1443
};
1444
1445
static const char *rssi_help =
1446
"Usage:\n"
1447
"\trssi <bdaddr>\n";
1448
1449
static void cmd_rssi(int dev_id, int argc, char **argv)
1450
{
1451
struct hci_conn_info_req *cr;
1452
bdaddr_t bdaddr;
1453
int8_t rssi;
1454
int opt, dd;
1455
1456
for_each_opt(opt, rssi_options, NULL) {
1457
switch (opt) {
1458
default:
1459
printf("%s", rssi_help);
1460
return;
1461
}
1462
}
1463
helper_arg(1, 1, &argc, &argv, rssi_help);
1464
1465
str2ba(argv[0], &bdaddr);
1466
1467
if (dev_id < 0) {
1468
dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
1469
if (dev_id < 0) {
1470
fprintf(stderr, "Not connected.\n");
1471
exit(1);
1472
}
1473
}
1474
1475
dd = hci_open_dev(dev_id);
1476
if (dd < 0) {
1477
perror("HCI device open failed");
1478
exit(1);
1479
}
1480
1481
cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
1482
if (!cr) {
1483
perror("Can't allocate memory");
1484
exit(1);
1485
}
1486
1487
bacpy(&cr->bdaddr, &bdaddr);
1488
cr->type = ACL_LINK;
1489
if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
1490
perror("Get connection info failed");
1491
exit(1);
1492
}
1493
1494
if (hci_read_rssi(dd, htobs(cr->conn_info->handle), &rssi, 1000) < 0) {
1495
perror("Read RSSI failed");
1496
exit(1);
1497
}
1498
1499
printf("RSSI return value: %d\n", rssi);
1500
1501
free(cr);
1502
1503
hci_close_dev(dd);
1504
}
1505
1506
/* Get link quality */
1507
1508
static struct option lq_options[] = {
1509
{ "help", 0, 0, 'h' },
1510
{ 0, 0, 0, 0 }
1511
};
1512
1513
static const char *lq_help =
1514
"Usage:\n"
1515
"\tlq <bdaddr>\n";
1516
1517
static void cmd_lq(int dev_id, int argc, char **argv)
1518
{
1519
struct hci_conn_info_req *cr;
1520
bdaddr_t bdaddr;
1521
uint8_t lq;
1522
int opt, dd;
1523
1524
for_each_opt(opt, lq_options, NULL) {
1525
switch (opt) {
1526
default:
1527
printf("%s", lq_help);
1528
return;
1529
}
1530
}
1531
helper_arg(1, 1, &argc, &argv, lq_help);
1532
1533
str2ba(argv[0], &bdaddr);
1534
1535
if (dev_id < 0) {
1536
dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
1537
if (dev_id < 0) {
1538
fprintf(stderr, "Not connected.\n");
1539
exit(1);
1540
}
1541
}
1542
1543
dd = hci_open_dev(dev_id);
1544
if (dd < 0) {
1545
perror("HCI device open failed");
1546
exit(1);
1547
}
1548
1549
cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
1550
if (!cr) {
1551
perror("Can't allocate memory");
1552
exit(1);
1553
}
1554
1555
bacpy(&cr->bdaddr, &bdaddr);
1556
cr->type = ACL_LINK;
1557
if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
1558
perror("Get connection info failed");
1559
exit(1);
1560
}
1561
1562
if (hci_read_link_quality(dd, htobs(cr->conn_info->handle), &lq, 1000) < 0) {
1563
perror("HCI read_link_quality request failed");
1564
exit(1);
1565
}
1566
1567
printf("Link quality: %d\n", lq);
1568
1569
free(cr);
1570
1571
hci_close_dev(dd);
1572
}
1573
1574
/* Get transmit power level */
1575
1576
static struct option tpl_options[] = {
1577
{ "help", 0, 0, 'h' },
1578
{ 0, 0, 0, 0 }
1579
};
1580
1581
static const char *tpl_help =
1582
"Usage:\n"
1583
"\ttpl <bdaddr> [type]\n";
1584
1585
static void cmd_tpl(int dev_id, int argc, char **argv)
1586
{
1587
struct hci_conn_info_req *cr;
1588
bdaddr_t bdaddr;
1589
uint8_t type;
1590
int8_t level;
1591
int opt, dd;
1592
1593
for_each_opt(opt, tpl_options, NULL) {
1594
switch (opt) {
1595
default:
1596
printf("%s", tpl_help);
1597
return;
1598
}
1599
}
1600
helper_arg(1, 2, &argc, &argv, tpl_help);
1601
1602
str2ba(argv[0], &bdaddr);
1603
type = (argc > 1) ? atoi(argv[1]) : 0;
1604
1605
if (dev_id < 0) {
1606
dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
1607
if (dev_id < 0) {
1608
fprintf(stderr, "Not connected.\n");
1609
exit(1);
1610
}
1611
}
1612
1613
dd = hci_open_dev(dev_id);
1614
if (dd < 0) {
1615
perror("HCI device open failed");
1616
exit(1);
1617
}
1618
1619
cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
1620
if (!cr) {
1621
perror("Can't allocate memory");
1622
exit(1);
1623
}
1624
1625
bacpy(&cr->bdaddr, &bdaddr);
1626
cr->type = ACL_LINK;
1627
if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
1628
perror("Get connection info failed");
1629
exit(1);
1630
}
1631
1632
if (hci_read_transmit_power_level(dd, htobs(cr->conn_info->handle), type, &level, 1000) < 0) {
1633
perror("HCI read transmit power level request failed");
1634
exit(1);
1635
}
1636
1637
printf("%s transmit power level: %d\n",
1638
(type == 0) ? "Current" : "Maximum", level);
1639
1640
free(cr);
1641
1642
hci_close_dev(dd);
1643
}
1644
1645
/* Get AFH channel map */
1646
1647
static struct option afh_options[] = {
1648
{ "help", 0, 0, 'h' },
1649
{ 0, 0, 0, 0 }
1650
};
1651
1652
static const char *afh_help =
1653
"Usage:\n"
1654
"\tafh <bdaddr>\n";
1655
1656
static void cmd_afh(int dev_id, int argc, char **argv)
1657
{
1658
struct hci_conn_info_req *cr;
1659
bdaddr_t bdaddr;
1660
uint16_t handle;
1661
uint8_t mode, map[10];
1662
int opt, dd;
1663
1664
for_each_opt(opt, afh_options, NULL) {
1665
switch (opt) {
1666
default:
1667
printf("%s", afh_help);
1668
return;
1669
}
1670
}
1671
helper_arg(1, 1, &argc, &argv, afh_help);
1672
1673
str2ba(argv[0], &bdaddr);
1674
1675
if (dev_id < 0) {
1676
dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
1677
if (dev_id < 0) {
1678
fprintf(stderr, "Not connected.\n");
1679
exit(1);
1680
}
1681
}
1682
1683
dd = hci_open_dev(dev_id);
1684
if (dd < 0) {
1685
perror("HCI device open failed");
1686
exit(1);
1687
}
1688
1689
cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
1690
if (!cr) {
1691
perror("Can't allocate memory");
1692
exit(1);
1693
}
1694
1695
bacpy(&cr->bdaddr, &bdaddr);
1696
cr->type = ACL_LINK;
1697
if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
1698
perror("Get connection info failed");
1699
exit(1);
1700
}
1701
1702
handle = htobs(cr->conn_info->handle);
1703
1704
if (hci_read_afh_map(dd, handle, &mode, map, 1000) < 0) {
1705
perror("HCI read AFH map request failed");
1706
exit(1);
1707
}
1708
1709
if (mode == 0x01) {
1710
int i;
1711
printf("AFH map: 0x");
1712
for (i = 0; i < 10; i++)
1713
printf("%02x", map[i]);
1714
printf("\n");
1715
} else
1716
printf("AFH disabled\n");
1717
1718
free(cr);
1719
1720
hci_close_dev(dd);
1721
}
1722
1723
/* Set connection packet type */
1724
1725
static struct option cpt_options[] = {
1726
{ "help", 0, 0, 'h' },
1727
{ 0, 0, 0, 0 }
1728
};
1729
1730
static const char *cpt_help =
1731
"Usage:\n"
1732
"\tcpt <bdaddr> <packet_types>\n";
1733
1734
static void cmd_cpt(int dev_id, int argc, char **argv)
1735
{
1736
struct hci_conn_info_req *cr;
1737
struct hci_request rq;
1738
set_conn_ptype_cp cp;
1739
evt_conn_ptype_changed rp;
1740
bdaddr_t bdaddr;
1741
unsigned int ptype;
1742
int dd, opt;
1743
1744
for_each_opt(opt, cpt_options, NULL) {
1745
switch (opt) {
1746
default:
1747
printf("%s", cpt_help);
1748
return;
1749
}
1750
}
1751
helper_arg(2, 2, &argc, &argv, cpt_help);
1752
1753
str2ba(argv[0], &bdaddr);
1754
hci_strtoptype(argv[1], &ptype);
1755
1756
if (dev_id < 0) {
1757
dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
1758
if (dev_id < 0) {
1759
fprintf(stderr, "Not connected.\n");
1760
exit(1);
1761
}
1762
}
1763
1764
dd = hci_open_dev(dev_id);
1765
if (dd < 0) {
1766
perror("HCI device open failed");
1767
exit(1);
1768
}
1769
1770
cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
1771
if (!cr) {
1772
perror("Can't allocate memory");
1773
exit(1);
1774
}
1775
1776
bacpy(&cr->bdaddr, &bdaddr);
1777
cr->type = ACL_LINK;
1778
if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
1779
perror("Get connection info failed");
1780
exit(1);
1781
}
1782
1783
cp.handle = htobs(cr->conn_info->handle);
1784
cp.pkt_type = ptype;
1785
1786
memset(&rq, 0, sizeof(rq));
1787
rq.ogf = OGF_LINK_CTL;
1788
rq.ocf = OCF_SET_CONN_PTYPE;
1789
rq.cparam = &cp;
1790
rq.clen = SET_CONN_PTYPE_CP_SIZE;
1791
rq.rparam = &rp;
1792
rq.rlen = EVT_CONN_PTYPE_CHANGED_SIZE;
1793
rq.event = EVT_CONN_PTYPE_CHANGED;
1794
1795
if (hci_send_req(dd, &rq, 100) < 0) {
1796
perror("Packet type change failed");
1797
exit(1);
1798
}
1799
1800
free(cr);
1801
1802
hci_close_dev(dd);
1803
}
1804
1805
/* Get/Set link policy settings */
1806
1807
static struct option lp_options[] = {
1808
{ "help", 0, 0, 'h' },
1809
{ 0, 0, 0, 0 }
1810
};
1811
1812
static const char *lp_help =
1813
"Usage:\n"
1814
"\tlp <bdaddr> [link policy]\n";
1815
1816
static void cmd_lp(int dev_id, int argc, char **argv)
1817
{
1818
struct hci_conn_info_req *cr;
1819
bdaddr_t bdaddr;
1820
uint16_t policy;
1821
int opt, dd;
1822
1823
for_each_opt(opt, lp_options, NULL) {
1824
switch (opt) {
1825
default:
1826
printf("%s", lp_help);
1827
return;
1828
}
1829
}
1830
helper_arg(1, 2, &argc, &argv, lp_help);
1831
1832
str2ba(argv[0], &bdaddr);
1833
1834
if (dev_id < 0) {
1835
dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
1836
if (dev_id < 0) {
1837
fprintf(stderr, "Not connected.\n");
1838
exit(1);
1839
}
1840
}
1841
1842
dd = hci_open_dev(dev_id);
1843
if (dd < 0) {
1844
perror("HCI device open failed");
1845
exit(1);
1846
}
1847
1848
cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
1849
if (!cr) {
1850
perror("Can't allocate memory");
1851
exit(1);
1852
}
1853
1854
bacpy(&cr->bdaddr, &bdaddr);
1855
cr->type = ACL_LINK;
1856
if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
1857
perror("Get connection info failed");
1858
exit(1);
1859
}
1860
1861
if (argc == 1) {
1862
char *str;
1863
if (hci_read_link_policy(dd, htobs(cr->conn_info->handle),
1864
&policy, 1000) < 0) {
1865
perror("HCI read_link_policy_settings request failed");
1866
exit(1);
1867
}
1868
1869
policy = btohs(policy);
1870
str = hci_lptostr(policy);
1871
if (str) {
1872
printf("Link policy settings: %s\n", str);
1873
bt_free(str);
1874
} else {
1875
fprintf(stderr, "Invalig settings\n");
1876
exit(1);
1877
}
1878
} else {
1879
unsigned int val;
1880
if (hci_strtolp(argv[1], &val) < 0) {
1881
fprintf(stderr, "Invalig arguments\n");
1882
exit(1);
1883
}
1884
policy = val;
1885
1886
if (hci_write_link_policy(dd, htobs(cr->conn_info->handle),
1887
htobs(policy), 1000) < 0) {
1888
perror("HCI write_link_policy_settings request failed");
1889
exit(1);
1890
}
1891
}
1892
1893
free(cr);
1894
1895
hci_close_dev(dd);
1896
}
1897
1898
/* Get/Set link supervision timeout */
1899
1900
static struct option lst_options[] = {
1901
{ "help", 0, 0, 'h' },
1902
{ 0, 0, 0, 0 }
1903
};
1904
1905
static const char *lst_help =
1906
"Usage:\n"
1907
"\tlst <bdaddr> [new value in slots]\n";
1908
1909
static void cmd_lst(int dev_id, int argc, char **argv)
1910
{
1911
struct hci_conn_info_req *cr;
1912
bdaddr_t bdaddr;
1913
uint16_t timeout;
1914
int opt, dd;
1915
1916
for_each_opt(opt, lst_options, NULL) {
1917
switch (opt) {
1918
default:
1919
printf("%s", lst_help);
1920
return;
1921
}
1922
}
1923
helper_arg(1, 2, &argc, &argv, lst_help);
1924
1925
str2ba(argv[0], &bdaddr);
1926
1927
if (dev_id < 0) {
1928
dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
1929
if (dev_id < 0) {
1930
fprintf(stderr, "Not connected.\n");
1931
exit(1);
1932
}
1933
}
1934
1935
dd = hci_open_dev(dev_id);
1936
if (dd < 0) {
1937
perror("HCI device open failed");
1938
exit(1);
1939
}
1940
1941
cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
1942
if (!cr) {
1943
perror("Can't allocate memory");
1944
exit(1);
1945
}
1946
1947
bacpy(&cr->bdaddr, &bdaddr);
1948
cr->type = ACL_LINK;
1949
if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
1950
perror("Get connection info failed");
1951
exit(1);
1952
}
1953
1954
if (argc == 1) {
1955
if (hci_read_link_supervision_timeout(dd, htobs(cr->conn_info->handle),
1956
&timeout, 1000) < 0) {
1957
perror("HCI read_link_supervision_timeout request failed");
1958
exit(1);
1959
}
1960
1961
timeout = btohs(timeout);
1962
1963
if (timeout)
1964
printf("Link supervision timeout: %u slots (%.2f msec)\n",
1965
timeout, (float) timeout * 0.625);
1966
else
1967
printf("Link supervision timeout never expires\n");
1968
} else {
1969
timeout = strtol(argv[1], NULL, 10);
1970
1971
if (hci_write_link_supervision_timeout(dd, htobs(cr->conn_info->handle),
1972
htobs(timeout), 1000) < 0) {
1973
perror("HCI write_link_supervision_timeout request failed");
1974
exit(1);
1975
}
1976
}
1977
1978
free(cr);
1979
1980
hci_close_dev(dd);
1981
}
1982
1983
/* Request authentication */
1984
1985
static struct option auth_options[] = {
1986
{ "help", 0, 0, 'h' },
1987
{ 0, 0, 0, 0 }
1988
};
1989
1990
static const char *auth_help =
1991
"Usage:\n"
1992
"\tauth <bdaddr>\n";
1993
1994
static void cmd_auth(int dev_id, int argc, char **argv)
1995
{
1996
struct hci_conn_info_req *cr;
1997
bdaddr_t bdaddr;
1998
int opt, dd;
1999
2000
for_each_opt(opt, auth_options, NULL) {
2001
switch (opt) {
2002
default:
2003
printf("%s", auth_help);
2004
return;
2005
}
2006
}
2007
helper_arg(1, 1, &argc, &argv, auth_help);
2008
2009
str2ba(argv[0], &bdaddr);
2010
2011
if (dev_id < 0) {
2012
dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
2013
if (dev_id < 0) {
2014
fprintf(stderr, "Not connected.\n");
2015
exit(1);
2016
}
2017
}
2018
2019
dd = hci_open_dev(dev_id);
2020
if (dd < 0) {
2021
perror("HCI device open failed");
2022
exit(1);
2023
}
2024
2025
cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
2026
if (!cr) {
2027
perror("Can't allocate memory");
2028
exit(1);
2029
}
2030
2031
bacpy(&cr->bdaddr, &bdaddr);
2032
cr->type = ACL_LINK;
2033
if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
2034
perror("Get connection info failed");
2035
exit(1);
2036
}
2037
2038
if (hci_authenticate_link(dd, htobs(cr->conn_info->handle), 25000) < 0) {
2039
perror("HCI authentication request failed");
2040
exit(1);
2041
}
2042
2043
free(cr);
2044
2045
hci_close_dev(dd);
2046
}
2047
2048
/* Activate encryption */
2049
2050
static struct option enc_options[] = {
2051
{ "help", 0, 0, 'h' },
2052
{ 0, 0, 0, 0 }
2053
};
2054
2055
static const char *enc_help =
2056
"Usage:\n"
2057
"\tenc <bdaddr> [encrypt enable]\n";
2058
2059
static void cmd_enc(int dev_id, int argc, char **argv)
2060
{
2061
struct hci_conn_info_req *cr;
2062
bdaddr_t bdaddr;
2063
uint8_t encrypt;
2064
int opt, dd;
2065
2066
for_each_opt(opt, enc_options, NULL) {
2067
switch (opt) {
2068
default:
2069
printf("%s", enc_help);
2070
return;
2071
}
2072
}
2073
helper_arg(1, 2, &argc, &argv, enc_help);
2074
2075
str2ba(argv[0], &bdaddr);
2076
2077
if (dev_id < 0) {
2078
dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
2079
if (dev_id < 0) {
2080
fprintf(stderr, "Not connected.\n");
2081
exit(1);
2082
}
2083
}
2084
2085
dd = hci_open_dev(dev_id);
2086
if (dd < 0) {
2087
perror("HCI device open failed");
2088
exit(1);
2089
}
2090
2091
cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
2092
if (!cr) {
2093
perror("Can't allocate memory");
2094
exit(1);
2095
}
2096
2097
bacpy(&cr->bdaddr, &bdaddr);
2098
cr->type = ACL_LINK;
2099
if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
2100
perror("Get connection info failed");
2101
exit(1);
2102
}
2103
2104
encrypt = (argc > 1) ? atoi(argv[1]) : 1;
2105
2106
if (hci_encrypt_link(dd, htobs(cr->conn_info->handle), encrypt, 25000) < 0) {
2107
perror("HCI set encryption request failed");
2108
exit(1);
2109
}
2110
2111
free(cr);
2112
2113
hci_close_dev(dd);
2114
}
2115
2116
/* Change connection link key */
2117
2118
static struct option key_options[] = {
2119
{ "help", 0, 0, 'h' },
2120
{ 0, 0, 0, 0 }
2121
};
2122
2123
static const char *key_help =
2124
"Usage:\n"
2125
"\tkey <bdaddr>\n";
2126
2127
static void cmd_key(int dev_id, int argc, char **argv)
2128
{
2129
struct hci_conn_info_req *cr;
2130
bdaddr_t bdaddr;
2131
int opt, dd;
2132
2133
for_each_opt(opt, key_options, NULL) {
2134
switch (opt) {
2135
default:
2136
printf("%s", key_help);
2137
return;
2138
}
2139
}
2140
helper_arg(1, 1, &argc, &argv, key_help);
2141
2142
str2ba(argv[0], &bdaddr);
2143
2144
if (dev_id < 0) {
2145
dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
2146
if (dev_id < 0) {
2147
fprintf(stderr, "Not connected.\n");
2148
exit(1);
2149
}
2150
}
2151
2152
dd = hci_open_dev(dev_id);
2153
if (dd < 0) {
2154
perror("HCI device open failed");
2155
exit(1);
2156
}
2157
2158
cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
2159
if (!cr) {
2160
perror("Can't allocate memory");
2161
exit(1);
2162
}
2163
2164
bacpy(&cr->bdaddr, &bdaddr);
2165
cr->type = ACL_LINK;
2166
if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
2167
perror("Get connection info failed");
2168
exit(1);
2169
}
2170
2171
if (hci_change_link_key(dd, htobs(cr->conn_info->handle), 25000) < 0) {
2172
perror("Changing link key failed");
2173
exit(1);
2174
}
2175
2176
free(cr);
2177
2178
hci_close_dev(dd);
2179
}
2180
2181
/* Read clock offset */
2182
2183
static struct option clkoff_options[] = {
2184
{ "help", 0, 0, 'h' },
2185
{ 0, 0, 0, 0 }
2186
};
2187
2188
static const char *clkoff_help =
2189
"Usage:\n"
2190
"\tclkoff <bdaddr>\n";
2191
2192
static void cmd_clkoff(int dev_id, int argc, char **argv)
2193
{
2194
struct hci_conn_info_req *cr;
2195
bdaddr_t bdaddr;
2196
uint16_t offset;
2197
int opt, dd;
2198
2199
for_each_opt(opt, clkoff_options, NULL) {
2200
switch (opt) {
2201
default:
2202
printf("%s", clkoff_help);
2203
return;
2204
}
2205
}
2206
helper_arg(1, 1, &argc, &argv, clkoff_help);
2207
2208
str2ba(argv[0], &bdaddr);
2209
2210
if (dev_id < 0) {
2211
dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
2212
if (dev_id < 0) {
2213
fprintf(stderr, "Not connected.\n");
2214
exit(1);
2215
}
2216
}
2217
2218
dd = hci_open_dev(dev_id);
2219
if (dd < 0) {
2220
perror("HCI device open failed");
2221
exit(1);
2222
}
2223
2224
cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
2225
if (!cr) {
2226
perror("Can't allocate memory");
2227
exit(1);
2228
}
2229
2230
bacpy(&cr->bdaddr, &bdaddr);
2231
cr->type = ACL_LINK;
2232
if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
2233
perror("Get connection info failed");
2234
exit(1);
2235
}
2236
2237
if (hci_read_clock_offset(dd, htobs(cr->conn_info->handle), &offset, 1000) < 0) {
2238
perror("Reading clock offset failed");
2239
exit(1);
2240
}
2241
2242
printf("Clock offset: 0x%4.4x\n", btohs(offset));
2243
2244
free(cr);
2245
2246
hci_close_dev(dd);
2247
}
2248
2249
/* Read clock */
2250
2251
static struct option clock_options[] = {
2252
{ "help", 0, 0, 'h' },
2253
{ 0, 0, 0, 0 }
2254
};
2255
2256
static const char *clock_help =
2257
"Usage:\n"
2258
"\tclock [bdaddr] [which clock]\n";
2259
2260
static void cmd_clock(int dev_id, int argc, char **argv)
2261
{
2262
struct hci_conn_info_req *cr;
2263
bdaddr_t bdaddr;
2264
uint8_t which;
2265
uint32_t handle, clock;
2266
uint16_t accuracy;
2267
int opt, dd;
2268
2269
for_each_opt(opt, clock_options, NULL) {
2270
switch (opt) {
2271
default:
2272
printf("%s", clock_help);
2273
return;
2274
}
2275
}
2276
helper_arg(0, 2, &argc, &argv, clock_help);
2277
2278
if (argc > 0)
2279
str2ba(argv[0], &bdaddr);
2280
else
2281
bacpy(&bdaddr, BDADDR_ANY);
2282
2283
if (dev_id < 0 && !bacmp(&bdaddr, BDADDR_ANY))
2284
dev_id = hci_get_route(NULL);
2285
2286
if (dev_id < 0) {
2287
dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
2288
if (dev_id < 0) {
2289
fprintf(stderr, "Not connected.\n");
2290
exit(1);
2291
}
2292
}
2293
2294
dd = hci_open_dev(dev_id);
2295
if (dd < 0) {
2296
perror("HCI device open failed");
2297
exit(1);
2298
}
2299
2300
if (bacmp(&bdaddr, BDADDR_ANY)) {
2301
cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
2302
if (!cr) {
2303
perror("Can't allocate memory");
2304
exit(1);
2305
}
2306
2307
bacpy(&cr->bdaddr, &bdaddr);
2308
cr->type = ACL_LINK;
2309
if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
2310
perror("Get connection info failed");
2311
free(cr);
2312
exit(1);
2313
}
2314
2315
handle = htobs(cr->conn_info->handle);
2316
which = (argc > 1) ? atoi(argv[1]) : 0x01;
2317
2318
free(cr);
2319
} else {
2320
handle = 0x00;
2321
which = 0x00;
2322
}
2323
2324
if (hci_read_clock(dd, handle, which, &clock, &accuracy, 1000) < 0) {
2325
perror("Reading clock failed");
2326
exit(1);
2327
}
2328
2329
accuracy = btohs(accuracy);
2330
2331
printf("Clock: 0x%4.4x\n", btohl(clock));
2332
printf("Accuracy: %.2f msec\n", (float) accuracy * 0.3125);
2333
2334
hci_close_dev(dd);
2335
}
2336
2337
static int read_flags(uint8_t *flags, const uint8_t *data, size_t size)
2338
{
2339
size_t offset;
2340
2341
if (!flags || !data)
2342
return -EINVAL;
2343
2344
offset = 0;
2345
while (offset < size) {
2346
uint8_t len = data[offset];
2347
uint8_t type;
2348
2349
/* Check if it is the end of the significant part */
2350
if (len == 0)
2351
break;
2352
2353
if (len + offset > size)
2354
break;
2355
2356
type = data[offset + 1];
2357
2358
if (type == FLAGS_AD_TYPE) {
2359
*flags = data[offset + 2];
2360
return 0;
2361
}
2362
2363
offset += 1 + len;
2364
}
2365
2366
return -ENOENT;
2367
}
2368
2369
static int check_report_filter(uint8_t procedure, le_advertising_info *info)
2370
{
2371
uint8_t flags;
2372
2373
/* If no discovery procedure is set, all reports are treat as valid */
2374
if (procedure == 0)
2375
return 1;
2376
2377
/* Read flags AD type value from the advertising report if it exists */
2378
if (read_flags(&flags, info->data, info->length))
2379
return 0;
2380
2381
switch (procedure) {
2382
case 'l': /* Limited Discovery Procedure */
2383
if (flags & FLAGS_LIMITED_MODE_BIT)
2384
return 1;
2385
break;
2386
case 'g': /* General Discovery Procedure */
2387
if (flags & (FLAGS_LIMITED_MODE_BIT | FLAGS_GENERAL_MODE_BIT))
2388
return 1;
2389
break;
2390
default:
2391
fprintf(stderr, "Unknown discovery procedure\n");
2392
}
2393
2394
return 0;
2395
}
2396
2397
static void sigint_handler(int sig)
2398
{
2399
signal_received = sig;
2400
}
2401
2402
static void eir_parse_name(uint8_t *eir, size_t eir_len,
2403
char *buf, size_t buf_len)
2404
{
2405
size_t offset;
2406
2407
offset = 0;
2408
while (offset < eir_len) {
2409
uint8_t field_len = eir[0];
2410
size_t name_len;
2411
2412
/* Check for the end of EIR */
2413
if (field_len == 0)
2414
break;
2415
2416
if (offset + field_len > eir_len)
2417
goto failed;
2418
2419
switch (eir[1]) {
2420
case EIR_NAME_SHORT:
2421
case EIR_NAME_COMPLETE:
2422
name_len = field_len - 1;
2423
if (name_len > buf_len)
2424
goto failed;
2425
2426
memcpy(buf, &eir[2], name_len);
2427
return;
2428
}
2429
2430
offset += field_len + 1;
2431
eir += field_len + 1;
2432
}
2433
2434
failed:
2435
snprintf(buf, buf_len, "(unknown)");
2436
}
2437
2438
static int print_advertising_devices(int dd, uint8_t filter_type)
2439
{
2440
unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr;
2441
struct hci_filter nf, of;
2442
struct sigaction sa;
2443
socklen_t olen;
2444
int len;
2445
2446
olen = sizeof(of);
2447
if (getsockopt(dd, SOL_HCI, HCI_FILTER, &of, &olen) < 0) {
2448
printf("Could not get socket options\n");
2449
return -1;
2450
}
2451
2452
hci_filter_clear(&nf);
2453
hci_filter_set_ptype(HCI_EVENT_PKT, &nf);
2454
hci_filter_set_event(EVT_LE_META_EVENT, &nf);
2455
2456
if (setsockopt(dd, SOL_HCI, HCI_FILTER, &nf, sizeof(nf)) < 0) {
2457
printf("Could not set socket options\n");
2458
return -1;
2459
}
2460
2461
memset(&sa, 0, sizeof(sa));
2462
sa.sa_flags = SA_NOCLDSTOP;
2463
sa.sa_handler = sigint_handler;
2464
sigaction(SIGINT, &sa, NULL);
2465
2466
while (1) {
2467
evt_le_meta_event *meta;
2468
le_advertising_info *info;
2469
char addr[18];
2470
2471
while ((len = read(dd, buf, sizeof(buf))) < 0) {
2472
if (errno == EINTR && signal_received == SIGINT) {
2473
len = 0;
2474
goto done;
2475
}
2476
2477
if (errno == EAGAIN || errno == EINTR)
2478
continue;
2479
goto done;
2480
}
2481
2482
ptr = buf + (1 + HCI_EVENT_HDR_SIZE);
2483
len -= (1 + HCI_EVENT_HDR_SIZE);
2484
2485
meta = (void *) ptr;
2486
2487
if (meta->subevent != 0x02)
2488
goto done;
2489
2490
/* Ignoring multiple reports */
2491
info = (le_advertising_info *) (meta->data + 1);
2492
if (check_report_filter(filter_type, info)) {
2493
char name[30];
2494
2495
memset(name, 0, sizeof(name));
2496
2497
ba2str(&info->bdaddr, addr);
2498
eir_parse_name(info->data, info->length,
2499
name, sizeof(name) - 1);
2500
2501
printf("%s %s\n", addr, name);
2502
}
2503
}
2504
2505
done:
2506
setsockopt(dd, SOL_HCI, HCI_FILTER, &of, sizeof(of));
2507
2508
if (len < 0)
2509
return -1;
2510
2511
return 0;
2512
}
2513
2514
static struct option lescan_options[] = {
2515
{ "help", 0, 0, 'h' },
2516
{ "privacy", 0, 0, 'p' },
2517
{ "passive", 0, 0, 'P' },
2518
{ "whitelist", 0, 0, 'w' },
2519
{ "discovery", 1, 0, 'd' },
2520
{ "duplicates", 0, 0, 'D' },
2521
{ 0, 0, 0, 0 }
2522
};
2523
2524
static const char *lescan_help =
2525
"Usage:\n"
2526
"\tlescan [--privacy] enable privacy\n"
2527
"\tlescan [--passive] set scan type passive (default active)\n"
2528
"\tlescan [--whitelist] scan for address in the whitelist only\n"
2529
"\tlescan [--discovery=g|l] enable general or limited discovery"
2530
"procedure\n"
2531
"\tlescan [--duplicates] don't filter duplicates\n";
2532
2533
static void cmd_lescan(int dev_id, int argc, char **argv)
2534
{
2535
int err, opt, dd;
2536
uint8_t own_type = 0x00;
2537
uint8_t scan_type = 0x01;
2538
uint8_t filter_type = 0;
2539
uint8_t filter_policy = 0x00;
2540
uint16_t interval = htobs(0x0010);
2541
uint16_t window = htobs(0x0010);
2542
uint8_t filter_dup = 1;
2543
2544
for_each_opt(opt, lescan_options, NULL) {
2545
switch (opt) {
2546
case 'p':
2547
own_type = 0x01; /* Random */
2548
break;
2549
case 'P':
2550
scan_type = 0x00; /* Passive */
2551
break;
2552
case 'w':
2553
filter_policy = 0x01; /* Whitelist */
2554
break;
2555
case 'd':
2556
filter_type = optarg[0];
2557
if (filter_type != 'g' && filter_type != 'l') {
2558
fprintf(stderr, "Unknown discovery procedure\n");
2559
exit(1);
2560
}
2561
2562
interval = htobs(0x0012);
2563
window = htobs(0x0012);
2564
break;
2565
case 'D':
2566
filter_dup = 0x00;
2567
break;
2568
default:
2569
printf("%s", lescan_help);
2570
return;
2571
}
2572
}
2573
helper_arg(0, 1, &argc, &argv, lescan_help);
2574
2575
if (dev_id < 0)
2576
dev_id = hci_get_route(NULL);
2577
2578
dd = hci_open_dev(dev_id);
2579
if (dd < 0) {
2580
perror("Could not open device");
2581
exit(1);
2582
}
2583
2584
err = hci_le_set_scan_parameters(dd, scan_type, interval, window,
2585
own_type, filter_policy, 1000);
2586
if (err < 0) {
2587
perror("Set scan parameters failed");
2588
exit(1);
2589
}
2590
2591
err = hci_le_set_scan_enable(dd, 0x01, filter_dup, 1000);
2592
if (err < 0) {
2593
perror("Enable scan failed");
2594
exit(1);
2595
}
2596
2597
printf("LE Scan ...\n");
2598
2599
err = print_advertising_devices(dd, filter_type);
2600
if (err < 0) {
2601
perror("Could not receive advertising events");
2602
exit(1);
2603
}
2604
2605
err = hci_le_set_scan_enable(dd, 0x00, filter_dup, 1000);
2606
if (err < 0) {
2607
perror("Disable scan failed");
2608
exit(1);
2609
}
2610
2611
hci_close_dev(dd);
2612
}
2613
2614
static struct option lecc_options[] = {
2615
{ "help", 0, 0, 'h' },
2616
{ "random", 0, 0, 'r' },
2617
{ "whitelist", 0, 0, 'w' },
2618
{ 0, 0, 0, 0 }
2619
};
2620
2621
static const char *lecc_help =
2622
"Usage:\n"
2623
"\tlecc [--random] <bdaddr>\n"
2624
"\tlecc --whitelist\n";
2625
2626
static void cmd_lecc(int dev_id, int argc, char **argv)
2627
{
2628
int err, opt, dd;
2629
bdaddr_t bdaddr;
2630
uint16_t interval, latency, max_ce_length, max_interval, min_ce_length;
2631
uint16_t min_interval, supervision_timeout, window, handle;
2632
uint8_t initiator_filter, own_bdaddr_type, peer_bdaddr_type;
2633
2634
peer_bdaddr_type = LE_PUBLIC_ADDRESS;
2635
initiator_filter = 0; /* Use peer address */
2636
2637
for_each_opt(opt, lecc_options, NULL) {
2638
switch (opt) {
2639
case 'r':
2640
peer_bdaddr_type = LE_RANDOM_ADDRESS;
2641
break;
2642
case 'w':
2643
initiator_filter = 0x01; /* Use white list */
2644
break;
2645
default:
2646
printf("%s", lecc_help);
2647
return;
2648
}
2649
}
2650
helper_arg(0, 1, &argc, &argv, lecc_help);
2651
2652
if (dev_id < 0)
2653
dev_id = hci_get_route(NULL);
2654
2655
dd = hci_open_dev(dev_id);
2656
if (dd < 0) {
2657
perror("Could not open device");
2658
exit(1);
2659
}
2660
2661
memset(&bdaddr, 0, sizeof(bdaddr_t));
2662
if (argv[0])
2663
str2ba(argv[0], &bdaddr);
2664
2665
interval = htobs(0x0004);
2666
window = htobs(0x0004);
2667
own_bdaddr_type = 0x00;
2668
min_interval = htobs(0x000F);
2669
max_interval = htobs(0x000F);
2670
latency = htobs(0x0000);
2671
supervision_timeout = htobs(0x0C80);
2672
min_ce_length = htobs(0x0001);
2673
max_ce_length = htobs(0x0001);
2674
2675
err = hci_le_create_conn(dd, interval, window, initiator_filter,
2676
peer_bdaddr_type, bdaddr, own_bdaddr_type, min_interval,
2677
max_interval, latency, supervision_timeout,
2678
min_ce_length, max_ce_length, &handle, 25000);
2679
if (err < 0) {
2680
perror("Could not create connection");
2681
exit(1);
2682
}
2683
2684
printf("Connection handle %d\n", handle);
2685
2686
hci_close_dev(dd);
2687
}
2688
2689
static struct option lewladd_options[] = {
2690
{ "help", 0, 0, 'h' },
2691
{ "random", 0, 0, 'r' },
2692
{ 0, 0, 0, 0 }
2693
};
2694
2695
static const char *lewladd_help =
2696
"Usage:\n"
2697
"\tlewladd [--random] <bdaddr>\n";
2698
2699
static void cmd_lewladd(int dev_id, int argc, char **argv)
2700
{
2701
int err, opt, dd;
2702
bdaddr_t bdaddr;
2703
uint8_t bdaddr_type = LE_PUBLIC_ADDRESS;
2704
2705
for_each_opt(opt, lewladd_options, NULL) {
2706
switch (opt) {
2707
case 'r':
2708
bdaddr_type = LE_RANDOM_ADDRESS;
2709
break;
2710
default:
2711
printf("%s", lewladd_help);
2712
return;
2713
}
2714
}
2715
2716
helper_arg(1, 1, &argc, &argv, lewladd_help);
2717
2718
if (dev_id < 0)
2719
dev_id = hci_get_route(NULL);
2720
2721
dd = hci_open_dev(dev_id);
2722
if (dd < 0) {
2723
perror("Could not open device");
2724
exit(1);
2725
}
2726
2727
str2ba(argv[0], &bdaddr);
2728
2729
err = hci_le_add_white_list(dd, &bdaddr, bdaddr_type, 1000);
2730
hci_close_dev(dd);
2731
2732
if (err < 0) {
2733
err = -errno;
2734
fprintf(stderr, "Can't add to white list: %s(%d)\n",
2735
strerror(-err), -err);
2736
exit(1);
2737
}
2738
}
2739
2740
static struct option lewlrm_options[] = {
2741
{ "help", 0, 0, 'h' },
2742
{ 0, 0, 0, 0 }
2743
};
2744
2745
static const char *lewlrm_help =
2746
"Usage:\n"
2747
"\tlewlrm <bdaddr>\n";
2748
2749
static void cmd_lewlrm(int dev_id, int argc, char **argv)
2750
{
2751
int err, opt, dd;
2752
bdaddr_t bdaddr;
2753
2754
for_each_opt(opt, lewlrm_options, NULL) {
2755
switch (opt) {
2756
default:
2757
printf("%s", lewlrm_help);
2758
return;
2759
}
2760
}
2761
2762
helper_arg(1, 1, &argc, &argv, lewlrm_help);
2763
2764
if (dev_id < 0)
2765
dev_id = hci_get_route(NULL);
2766
2767
dd = hci_open_dev(dev_id);
2768
if (dd < 0) {
2769
perror("Could not open device");
2770
exit(1);
2771
}
2772
2773
str2ba(argv[0], &bdaddr);
2774
2775
err = hci_le_rm_white_list(dd, &bdaddr, LE_PUBLIC_ADDRESS, 1000);
2776
hci_close_dev(dd);
2777
2778
if (err < 0) {
2779
err = errno;
2780
fprintf(stderr, "Can't remove from white list: %s(%d)\n",
2781
strerror(err), err);
2782
exit(1);
2783
}
2784
}
2785
2786
static struct option lewlsz_options[] = {
2787
{ "help", 0, 0, 'h' },
2788
{ 0, 0, 0, 0 }
2789
};
2790
2791
static const char *lewlsz_help =
2792
"Usage:\n"
2793
"\tlewlsz\n";
2794
2795
static void cmd_lewlsz(int dev_id, int argc, char **argv)
2796
{
2797
int err, dd, opt;
2798
uint8_t size;
2799
2800
for_each_opt(opt, lewlsz_options, NULL) {
2801
switch (opt) {
2802
default:
2803
printf("%s", lewlsz_help);
2804
return;
2805
}
2806
}
2807
2808
helper_arg(0, 0, &argc, &argv, lewlsz_help);
2809
2810
if (dev_id < 0)
2811
dev_id = hci_get_route(NULL);
2812
2813
dd = hci_open_dev(dev_id);
2814
if (dd < 0) {
2815
perror("Could not open device");
2816
exit(1);
2817
}
2818
2819
err = hci_le_read_white_list_size(dd, &size, 1000);
2820
hci_close_dev(dd);
2821
2822
if (err < 0) {
2823
err = -errno;
2824
fprintf(stderr, "Can't read white list size: %s(%d)\n",
2825
strerror(-err), -err);
2826
exit(1);
2827
}
2828
2829
printf("White list size: %d\n", size);
2830
}
2831
2832
static struct option lewlclr_options[] = {
2833
{ "help", 0, 0, 'h' },
2834
{ 0, 0, 0, 0 }
2835
};
2836
2837
static const char *lewlclr_help =
2838
"Usage:\n"
2839
"\tlewlclr\n";
2840
2841
static void cmd_lewlclr(int dev_id, int argc, char **argv)
2842
{
2843
int err, dd, opt;
2844
2845
for_each_opt(opt, lewlclr_options, NULL) {
2846
switch (opt) {
2847
default:
2848
printf("%s", lewlclr_help);
2849
return;
2850
}
2851
}
2852
2853
helper_arg(0, 0, &argc, &argv, lewlclr_help);
2854
2855
if (dev_id < 0)
2856
dev_id = hci_get_route(NULL);
2857
2858
dd = hci_open_dev(dev_id);
2859
if (dd < 0) {
2860
perror("Could not open device");
2861
exit(1);
2862
}
2863
2864
err = hci_le_clear_white_list(dd, 1000);
2865
hci_close_dev(dd);
2866
2867
if (err < 0) {
2868
err = -errno;
2869
fprintf(stderr, "Can't clear white list: %s(%d)\n",
2870
strerror(-err), -err);
2871
exit(1);
2872
}
2873
}
2874
2875
static struct option ledc_options[] = {
2876
{ "help", 0, 0, 'h' },
2877
{ 0, 0, 0, 0 }
2878
};
2879
2880
static const char *ledc_help =
2881
"Usage:\n"
2882
"\tledc <handle> [reason]\n";
2883
2884
static void cmd_ledc(int dev_id, int argc, char **argv)
2885
{
2886
int err, opt, dd;
2887
uint16_t handle;
2888
uint8_t reason;
2889
2890
for_each_opt(opt, ledc_options, NULL) {
2891
switch (opt) {
2892
default:
2893
printf("%s", ledc_help);
2894
return;
2895
}
2896
}
2897
helper_arg(1, 2, &argc, &argv, ledc_help);
2898
2899
if (dev_id < 0)
2900
dev_id = hci_get_route(NULL);
2901
2902
dd = hci_open_dev(dev_id);
2903
if (dd < 0) {
2904
perror("Could not open device");
2905
exit(1);
2906
}
2907
2908
handle = atoi(argv[0]);
2909
2910
reason = (argc > 1) ? atoi(argv[1]) : HCI_OE_USER_ENDED_CONNECTION;
2911
2912
err = hci_disconnect(dd, handle, reason, 10000);
2913
if (err < 0) {
2914
perror("Could not disconnect");
2915
exit(1);
2916
}
2917
2918
hci_close_dev(dd);
2919
}
2920
2921
static struct option lecup_options[] = {
2922
{ "help", 0, 0, 'h' },
2923
{ "handle", 1, 0, 'H' },
2924
{ "min", 1, 0, 'm' },
2925
{ "max", 1, 0, 'M' },
2926
{ "latency", 1, 0, 'l' },
2927
{ "timeout", 1, 0, 't' },
2928
{ 0, 0, 0, 0 }
2929
};
2930
2931
static const char *lecup_help =
2932
"Usage:\n"
2933
"\tlecup <handle> <min> <max> <latency> <timeout>\n"
2934
"\tOptions:\n"
2935
"\t -H, --handle <0xXXXX> LE connection handle\n"
2936
"\t -m, --min <interval> Range: 0x0006 to 0x0C80\n"
2937
"\t -M, --max <interval> Range: 0x0006 to 0x0C80\n"
2938
"\t -l, --latency <range> Slave latency. Range: 0x0000 to 0x03E8\n"
2939
"\t -t, --timeout <time> N * 10ms. Range: 0x000A to 0x0C80\n"
2940
"\n\t min/max range: 7.5ms to 4s. Multiply factor: 1.25ms"
2941
"\n\t timeout range: 100ms to 32.0s. Larger than max interval\n";
2942
2943
static void cmd_lecup(int dev_id, int argc, char **argv)
2944
{
2945
uint16_t handle = 0, min, max, latency, timeout;
2946
int opt, dd, base;
2947
2948
/* Aleatory valid values */
2949
min = 0x0C8;
2950
max = 0x0960;
2951
latency = 0x0007;
2952
timeout = 0x0C80;
2953
2954
for_each_opt(opt, lecup_options, NULL) {
2955
if (optarg && strncasecmp("0x", optarg, 2) == 0)
2956
base = 16;
2957
else
2958
base = 10;
2959
2960
switch (opt) {
2961
case 'H':
2962
handle = strtoul(optarg, NULL, base);
2963
break;
2964
case 'm':
2965
min = strtoul(optarg, NULL, base);
2966
break;
2967
case 'M':
2968
max = strtoul(optarg, NULL, base);
2969
break;
2970
case 'l':
2971
latency = strtoul(optarg, NULL, base);
2972
break;
2973
case 't':
2974
timeout = strtoul(optarg, NULL, base);
2975
break;
2976
default:
2977
printf("%s", lecup_help);
2978
return;
2979
}
2980
}
2981
2982
if (handle == 0) {
2983
printf("%s", lecup_help);
2984
return;
2985
}
2986
2987
if (dev_id < 0)
2988
dev_id = hci_get_route(NULL);
2989
2990
dd = hci_open_dev(dev_id);
2991
if (dd < 0) {
2992
fprintf(stderr, "HCI device open failed\n");
2993
exit(1);
2994
}
2995
2996
if (hci_le_conn_update(dd, htobs(handle), htobs(min), htobs(max),
2997
htobs(latency), htobs(timeout), 5000) < 0) {
2998
int err = -errno;
2999
fprintf(stderr, "Could not change connection params: %s(%d)\n",
3000
strerror(-err), -err);
3001
}
3002
3003
hci_close_dev(dd);
3004
}
3005
3006
static struct {
3007
char *cmd;
3008
void (*func)(int dev_id, int argc, char **argv);
3009
char *doc;
3010
} command[] = {
3011
{ "dev", cmd_dev, "Display local devices" },
3012
{ "inq", cmd_inq, "Inquire remote devices" },
3013
{ "scan", cmd_scan, "Scan for remote devices" },
3014
{ "name", cmd_name, "Get name from remote device" },
3015
{ "info", cmd_info, "Get information from remote device" },
3016
{ "spinq", cmd_spinq, "Start periodic inquiry" },
3017
{ "epinq", cmd_epinq, "Exit periodic inquiry" },
3018
{ "cmd", cmd_cmd, "Submit arbitrary HCI commands" },
3019
{ "con", cmd_con, "Display active connections" },
3020
{ "cc", cmd_cc, "Create connection to remote device" },
3021
{ "dc", cmd_dc, "Disconnect from remote device" },
3022
{ "sr", cmd_sr, "Switch master/slave role" },
3023
{ "cpt", cmd_cpt, "Change connection packet type" },
3024
{ "rssi", cmd_rssi, "Display connection RSSI" },
3025
{ "lq", cmd_lq, "Display link quality" },
3026
{ "tpl", cmd_tpl, "Display transmit power level" },
3027
{ "afh", cmd_afh, "Display AFH channel map" },
3028
{ "lp", cmd_lp, "Set/display link policy settings" },
3029
{ "lst", cmd_lst, "Set/display link supervision timeout" },
3030
{ "auth", cmd_auth, "Request authentication" },
3031
{ "enc", cmd_enc, "Set connection encryption" },
3032
{ "key", cmd_key, "Change connection link key" },
3033
{ "clkoff", cmd_clkoff, "Read clock offset" },
3034
{ "clock", cmd_clock, "Read local or remote clock" },
3035
{ "lescan", cmd_lescan, "Start LE scan" },
3036
{ "lewladd", cmd_lewladd, "Add device to LE White List" },
3037
{ "lewlrm", cmd_lewlrm, "Remove device from LE White List" },
3038
{ "lewlsz", cmd_lewlsz, "Read size of LE White List" },
3039
{ "lewlclr", cmd_lewlclr, "Clear LE White list" },
3040
{ "lecc", cmd_lecc, "Create a LE Connection" },
3041
{ "ledc", cmd_ledc, "Disconnect a LE Connection" },
3042
{ "lecup", cmd_lecup, "LE Connection Update" },
3043
{ NULL, NULL, 0 }
3044
};
3045
3046
static void usage(void)
3047
{
3048
int i;
3049
3050
// printf("hcitool - HCI Tool ver %s\n", VERSION);
3051
printf("Usage:\n"
3052
"\thcitool [options] <command> [command parameters]\n");
3053
printf("Options:\n"
3054
"\t--help\tDisplay help\n"
3055
"\t-i dev\tHCI device\n");
3056
printf("Commands:\n");
3057
for (i = 0; command[i].cmd; i++)
3058
printf("\t%-4s\t%s\n", command[i].cmd,
3059
command[i].doc);
3060
printf("\n"
3061
"For more information on the usage of each command use:\n"
3062
"\thcitool <command> --help\n" );
3063
}
3064
3065
static struct option main_options[] = {
3066
{ "help", 0, 0, 'h' },
3067
{ "device", 1, 0, 'i' },
3068
{ 0, 0, 0, 0 }
3069
};
3070
3071
int main(int argc, char *argv[])
3072
{
3073
int opt, i, dev_id = -1;
3074
bdaddr_t ba;
3075
3076
while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) {
3077
switch (opt) {
3078
case 'i':
3079
dev_id = hci_devid(optarg);
3080
if (dev_id < 0) {
3081
perror("Invalid device");
3082
exit(1);
3083
}
3084
break;
3085
3086
case 'h':
3087
default:
3088
usage();
3089
exit(0);
3090
}
3091
}
3092
3093
argc -= optind;
3094
argv += optind;
3095
optind = 0;
3096
3097
if (argc < 1) {
3098
usage();
3099
exit(0);
3100
}
3101
3102
if (dev_id != -1 && hci_devba(dev_id, &ba) < 0) {
3103
perror("Device is not available");
3104
exit(1);
3105
}
3106
3107
for (i = 0; command[i].cmd; i++) {
3108
if (strncmp(command[i].cmd,
3109
argv[0], strlen(command[i].cmd)))
3110
continue;
3111
3112
command[i].func(dev_id, argc, argv);
3113
break;
3114
}
3115
3116
if (command[i].cmd == 0) {
3117
fprintf(stderr, "Unknown command - \"%s\"\n", *argv);
3118
exit(1);
3119
}
3120
3121
return 0;
3122
}
3123
3124