Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
orangepi-xunlong
GitHub Repository: orangepi-xunlong/orangepi-build
Path: blob/next/external/cache/sources/hcitools/hciconfig.c
17847 views
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 <unistd.h>
34
#include <stdlib.h>
35
#include <string.h>
36
#include <getopt.h>
37
#include <sys/param.h>
38
#include <sys/ioctl.h>
39
#include <sys/socket.h>
40
41
#include <bluetooth/bluetooth.h>
42
#include <bluetooth/hci.h>
43
#include <bluetooth/hci_lib.h>
44
45
#include "textfile.h"
46
#include "csr.h"
47
48
static struct hci_dev_info di;
49
static int all;
50
51
static void print_dev_hdr(struct hci_dev_info *di);
52
static void print_dev_info(int ctl, struct hci_dev_info *di);
53
54
static void print_dev_list(int ctl, int flags)
55
{
56
struct hci_dev_list_req *dl;
57
struct hci_dev_req *dr;
58
int i;
59
60
if (!(dl = malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) +
61
sizeof(uint16_t)))) {
62
perror("Can't allocate memory");
63
exit(1);
64
}
65
dl->dev_num = HCI_MAX_DEV;
66
dr = dl->dev_req;
67
68
if (ioctl(ctl, HCIGETDEVLIST, (void *) dl) < 0) {
69
perror("Can't get device list");
70
if(dl) {
71
free(dl);
72
dl = NULL;
73
}
74
exit(1);
75
}
76
77
for (i = 0; i< dl->dev_num; i++) {
78
di.dev_id = (dr+i)->dev_id;
79
if (ioctl(ctl, HCIGETDEVINFO, (void *) &di) < 0)
80
continue;
81
if (hci_test_bit(HCI_RAW, &di.flags) &&
82
!bacmp(&di.bdaddr, BDADDR_ANY)) {
83
int dd = hci_open_dev(di.dev_id);
84
hci_read_bd_addr(dd, &di.bdaddr, 1000);
85
hci_close_dev(dd);
86
}
87
print_dev_info(ctl, &di);
88
}
89
if(dl) {
90
free(dl);
91
dl = NULL;
92
}
93
}
94
95
static void print_pkt_type(struct hci_dev_info *di)
96
{
97
char *str;
98
str = hci_ptypetostr(di->pkt_type);
99
printf("\tPacket type: %s\n", str);
100
bt_free(str);
101
}
102
103
static void print_link_policy(struct hci_dev_info *di)
104
{
105
printf("\tLink policy: %s\n", hci_lptostr(di->link_policy));
106
}
107
108
static void print_link_mode(struct hci_dev_info *di)
109
{
110
char *str;
111
str = hci_lmtostr(di->link_mode);
112
printf("\tLink mode: %s\n", str);
113
bt_free(str);
114
}
115
116
static void print_dev_features(struct hci_dev_info *di, int format)
117
{
118
printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
119
"0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n",
120
di->features[0], di->features[1], di->features[2],
121
di->features[3], di->features[4], di->features[5],
122
di->features[6], di->features[7]);
123
124
if (format) {
125
char *tmp = lmp_featurestostr(di->features, "\t\t", 63);
126
printf("%s\n", tmp);
127
bt_free(tmp);
128
}
129
}
130
131
static void print_le_states(uint64_t states)
132
{
133
int i;
134
const char *le_states[] = {
135
"Non-connectable Advertising State" ,
136
"Scannable Advertising State",
137
"Connectable Advertising State",
138
"Directed Advertising State",
139
"Passive Scanning State",
140
"Active Scanning State",
141
"Initiating State/Connection State in Master Role",
142
"Connection State in the Slave Role",
143
"Non-connectable Advertising State and Passive Scanning State combination",
144
"Scannable Advertising State and Passive Scanning State combination",
145
"Connectable Advertising State and Passive Scanning State combination",
146
"Directed Advertising State and Passive Scanning State combination",
147
"Non-connectable Advertising State and Active Scanning State combination",
148
"Scannable Advertising State and Active Scanning State combination",
149
"Connectable Advertising State and Active Scanning State combination",
150
"Directed Advertising State and Active Scanning State combination",
151
"Non-connectable Advertising State and Initiating State combination",
152
"Scannable Advertising State and Initiating State combination",
153
"Non-connectable Advertising State and Master Role combination",
154
"Scannable Advertising State and Master Role combination",
155
"Non-connectable Advertising State and Slave Role combination",
156
"Scannable Advertising State and Slave Role combination",
157
"Passive Scanning State and Initiating State combination",
158
"Active Scanning State and Initiating State combination",
159
"Passive Scanning State and Master Role combination",
160
"Active Scanning State and Master Role combination",
161
"Passive Scanning State and Slave Role combination",
162
"Active Scanning State and Slave Role combination",
163
"Initiating State and Master Role combination/Master Role and Master Role combination",
164
NULL
165
};
166
167
printf("Supported link layer states:\n");
168
for (i = 0; le_states[i]; i++) {
169
const char *status;
170
171
status = states & (1 << i) ? "YES" : "NO ";
172
printf("\t%s %s\n", status, le_states[i]);
173
}
174
}
175
176
static void cmd_rstat(int ctl, int hdev, char *opt)
177
{
178
/* Reset HCI device stat counters */
179
if (ioctl(ctl, HCIDEVRESTAT, hdev) < 0) {
180
fprintf(stderr, "Can't reset stats counters hci%d: %s (%d)\n",
181
hdev, strerror(errno), errno);
182
exit(1);
183
}
184
}
185
186
static void cmd_scan(int ctl, int hdev, char *opt)
187
{
188
struct hci_dev_req dr;
189
190
dr.dev_id = hdev;
191
dr.dev_opt = SCAN_DISABLED;
192
if (!strcmp(opt, "iscan"))
193
dr.dev_opt = SCAN_INQUIRY;
194
else if (!strcmp(opt, "pscan"))
195
dr.dev_opt = SCAN_PAGE;
196
else if (!strcmp(opt, "piscan"))
197
dr.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
198
199
if (ioctl(ctl, HCISETSCAN, (unsigned long) &dr) < 0) {
200
fprintf(stderr, "Can't set scan mode on hci%d: %s (%d)\n",
201
hdev, strerror(errno), errno);
202
exit(1);
203
}
204
}
205
206
static void cmd_le_addr(int ctl, int hdev, char *opt)
207
{
208
struct hci_request rq;
209
le_set_random_address_cp cp;
210
uint8_t status;
211
int dd, err, ret;
212
213
if (!opt)
214
return;
215
216
if (hdev < 0)
217
hdev = hci_get_route(NULL);
218
219
dd = hci_open_dev(hdev);
220
if (dd < 0) {
221
err = -errno;
222
fprintf(stderr, "Could not open device: %s(%d)\n",
223
strerror(-err), -err);
224
exit(1);
225
}
226
227
memset(&cp, 0, sizeof(cp));
228
229
str2ba(opt, &cp.bdaddr);
230
231
memset(&rq, 0, sizeof(rq));
232
rq.ogf = OGF_LE_CTL;
233
rq.ocf = OCF_LE_SET_RANDOM_ADDRESS;
234
rq.cparam = &cp;
235
rq.clen = LE_SET_RANDOM_ADDRESS_CP_SIZE;
236
rq.rparam = &status;
237
rq.rlen = 1;
238
239
ret = hci_send_req(dd, &rq, 1000);
240
if (status || ret < 0) {
241
err = -errno;
242
fprintf(stderr, "Can't set random address for hci%d: "
243
"%s (%d)\n", hdev, strerror(-err), -err);
244
}
245
246
hci_close_dev(dd);
247
}
248
249
static void cmd_le_adv(int ctl, int hdev, char *opt)
250
{
251
struct hci_request rq;
252
le_set_advertise_enable_cp advertise_cp;
253
le_set_advertising_parameters_cp adv_params_cp;
254
uint8_t status;
255
int dd, ret;
256
257
if (hdev < 0)
258
hdev = hci_get_route(NULL);
259
260
dd = hci_open_dev(hdev);
261
if (dd < 0) {
262
perror("Could not open device");
263
exit(1);
264
}
265
266
memset(&adv_params_cp, 0, sizeof(adv_params_cp));
267
adv_params_cp.min_interval = htobs(0x0800);
268
adv_params_cp.max_interval = htobs(0x0800);
269
if (opt)
270
adv_params_cp.advtype = atoi(opt);
271
adv_params_cp.chan_map = 7;
272
273
memset(&rq, 0, sizeof(rq));
274
rq.ogf = OGF_LE_CTL;
275
rq.ocf = OCF_LE_SET_ADVERTISING_PARAMETERS;
276
rq.cparam = &adv_params_cp;
277
rq.clen = LE_SET_ADVERTISING_PARAMETERS_CP_SIZE;
278
rq.rparam = &status;
279
rq.rlen = 1;
280
281
ret = hci_send_req(dd, &rq, 1000);
282
if (ret < 0)
283
goto done;
284
285
memset(&advertise_cp, 0, sizeof(advertise_cp));
286
advertise_cp.enable = 0x01;
287
288
memset(&rq, 0, sizeof(rq));
289
rq.ogf = OGF_LE_CTL;
290
rq.ocf = OCF_LE_SET_ADVERTISE_ENABLE;
291
rq.cparam = &advertise_cp;
292
rq.clen = LE_SET_ADVERTISE_ENABLE_CP_SIZE;
293
rq.rparam = &status;
294
rq.rlen = 1;
295
296
ret = hci_send_req(dd, &rq, 1000);
297
298
done:
299
hci_close_dev(dd);
300
301
if (ret < 0) {
302
fprintf(stderr, "Can't set advertise mode on hci%d: %s (%d)\n",
303
hdev, strerror(errno), errno);
304
exit(1);
305
}
306
307
if (status) {
308
fprintf(stderr,
309
"LE set advertise enable on hci%d returned status %d\n",
310
hdev, status);
311
exit(1);
312
}
313
}
314
315
static void cmd_no_le_adv(int ctl, int hdev, char *opt)
316
{
317
struct hci_request rq;
318
le_set_advertise_enable_cp advertise_cp;
319
uint8_t status;
320
int dd, ret;
321
322
if (hdev < 0)
323
hdev = hci_get_route(NULL);
324
325
dd = hci_open_dev(hdev);
326
if (dd < 0) {
327
perror("Could not open device");
328
exit(1);
329
}
330
331
memset(&advertise_cp, 0, sizeof(advertise_cp));
332
333
memset(&rq, 0, sizeof(rq));
334
rq.ogf = OGF_LE_CTL;
335
rq.ocf = OCF_LE_SET_ADVERTISE_ENABLE;
336
rq.cparam = &advertise_cp;
337
rq.clen = LE_SET_ADVERTISE_ENABLE_CP_SIZE;
338
rq.rparam = &status;
339
rq.rlen = 1;
340
341
ret = hci_send_req(dd, &rq, 1000);
342
343
hci_close_dev(dd);
344
345
if (ret < 0) {
346
fprintf(stderr, "Can't set advertise mode on hci%d: %s (%d)\n",
347
hdev, strerror(errno), errno);
348
exit(1);
349
}
350
351
if (status) {
352
fprintf(stderr, "LE set advertise enable on hci%d returned status %d\n",
353
hdev, status);
354
exit(1);
355
}
356
}
357
358
static void cmd_le_states(int ctl, int hdev, char *opt)
359
{
360
le_read_supported_states_rp rp;
361
struct hci_request rq;
362
int err, dd;
363
364
if (hdev < 0)
365
hdev = hci_get_route(NULL);
366
367
dd = hci_open_dev(hdev);
368
if (dd < 0) {
369
fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
370
hdev, strerror(errno), errno);
371
exit(1);
372
}
373
374
memset(&rp, 0, sizeof(rp));
375
memset(&rq, 0, sizeof(rq));
376
377
rq.ogf = OGF_LE_CTL;
378
rq.ocf = OCF_LE_READ_SUPPORTED_STATES;
379
rq.rparam = &rp;
380
rq.rlen = LE_READ_SUPPORTED_STATES_RP_SIZE;
381
382
err = hci_send_req(dd, &rq, 1000);
383
384
hci_close_dev(dd);
385
386
if (err < 0) {
387
fprintf(stderr, "Can't read LE supported states on hci%d:"
388
" %s(%d)\n", hdev, strerror(errno), errno);
389
exit(1);
390
}
391
392
if (rp.status) {
393
fprintf(stderr, "Read LE supported states on hci%d"
394
" returned status %d\n", hdev, rp.status);
395
exit(1);
396
}
397
398
print_le_states(rp.states);
399
}
400
401
static void cmd_iac(int ctl, int hdev, char *opt)
402
{
403
int s = hci_open_dev(hdev);
404
405
if (s < 0) {
406
fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
407
hdev, strerror(errno), errno);
408
exit(1);
409
}
410
if (opt) {
411
int l = strtoul(opt, 0, 16);
412
uint8_t lap[3];
413
if (!strcasecmp(opt, "giac")) {
414
l = 0x9e8b33;
415
} else if (!strcasecmp(opt, "liac")) {
416
l = 0x9e8b00;
417
} else if (l < 0x9e8b00 || l > 0x9e8b3f) {
418
printf("Invalid access code 0x%x\n", l);
419
exit(1);
420
}
421
lap[0] = (l & 0xff);
422
lap[1] = (l >> 8) & 0xff;
423
lap[2] = (l >> 16) & 0xff;
424
if (hci_write_current_iac_lap(s, 1, lap, 1000) < 0) {
425
printf("Failed to set IAC on hci%d: %s\n", hdev, strerror(errno));
426
exit(1);
427
}
428
} else {
429
uint8_t lap[3 * MAX_IAC_LAP];
430
int i, j;
431
uint8_t n;
432
if (hci_read_current_iac_lap(s, &n, lap, 1000) < 0) {
433
printf("Failed to read IAC from hci%d: %s\n", hdev, strerror(errno));
434
exit(1);
435
}
436
print_dev_hdr(&di);
437
printf("\tIAC: ");
438
for (i = 0; i < n; i++) {
439
printf("0x");
440
for (j = 3; j--; )
441
printf("%02x", lap[j + 3 * i]);
442
if (i < n - 1)
443
printf(", ");
444
}
445
printf("\n");
446
}
447
close(s);
448
}
449
450
static void cmd_auth(int ctl, int hdev, char *opt)
451
{
452
struct hci_dev_req dr;
453
454
dr.dev_id = hdev;
455
if (!strcmp(opt, "auth"))
456
dr.dev_opt = AUTH_ENABLED;
457
else
458
dr.dev_opt = AUTH_DISABLED;
459
460
if (ioctl(ctl, HCISETAUTH, (unsigned long) &dr) < 0) {
461
fprintf(stderr, "Can't set auth on hci%d: %s (%d)\n",
462
hdev, strerror(errno), errno);
463
exit(1);
464
}
465
}
466
467
static void cmd_encrypt(int ctl, int hdev, char *opt)
468
{
469
struct hci_dev_req dr;
470
471
dr.dev_id = hdev;
472
if (!strcmp(opt, "encrypt"))
473
dr.dev_opt = ENCRYPT_P2P;
474
else
475
dr.dev_opt = ENCRYPT_DISABLED;
476
477
if (ioctl(ctl, HCISETENCRYPT, (unsigned long) &dr) < 0) {
478
fprintf(stderr, "Can't set encrypt on hci%d: %s (%d)\n",
479
hdev, strerror(errno), errno);
480
exit(1);
481
}
482
}
483
484
static void cmd_up(int ctl, int hdev, char *opt)
485
{
486
/* Start HCI device */
487
if (ioctl(ctl, HCIDEVUP, hdev) < 0) {
488
if (errno == EALREADY)
489
return;
490
fprintf(stderr, "Can't init device hci%d: %s (%d)\n",
491
hdev, strerror(errno), errno);
492
exit(1);
493
}
494
}
495
496
static void cmd_down(int ctl, int hdev, char *opt)
497
{
498
/* Stop HCI device */
499
if (ioctl(ctl, HCIDEVDOWN, hdev) < 0) {
500
fprintf(stderr, "Can't down device hci%d: %s (%d)\n",
501
hdev, strerror(errno), errno);
502
exit(1);
503
}
504
}
505
506
static void cmd_reset(int ctl, int hdev, char *opt)
507
{
508
/* Reset HCI device */
509
#if 0
510
if (ioctl(ctl, HCIDEVRESET, hdev) < 0 ){
511
fprintf(stderr, "Reset failed for device hci%d: %s (%d)\n",
512
hdev, strerror(errno), errno);
513
exit(1);
514
}
515
#endif
516
cmd_down(ctl, hdev, "down");
517
cmd_up(ctl, hdev, "up");
518
}
519
520
static void cmd_ptype(int ctl, int hdev, char *opt)
521
{
522
struct hci_dev_req dr;
523
524
dr.dev_id = hdev;
525
526
if (hci_strtoptype(opt, &dr.dev_opt)) {
527
if (ioctl(ctl, HCISETPTYPE, (unsigned long) &dr) < 0) {
528
fprintf(stderr, "Can't set pkttype on hci%d: %s (%d)\n",
529
hdev, strerror(errno), errno);
530
exit(1);
531
}
532
} else {
533
print_dev_hdr(&di);
534
print_pkt_type(&di);
535
}
536
}
537
538
static void cmd_lp(int ctl, int hdev, char *opt)
539
{
540
struct hci_dev_req dr;
541
542
dr.dev_id = hdev;
543
544
if (hci_strtolp(opt, &dr.dev_opt)) {
545
if (ioctl(ctl, HCISETLINKPOL, (unsigned long) &dr) < 0) {
546
fprintf(stderr, "Can't set link policy on hci%d: %s (%d)\n",
547
hdev, strerror(errno), errno);
548
exit(1);
549
}
550
} else {
551
print_dev_hdr(&di);
552
print_link_policy(&di);
553
}
554
}
555
556
static void cmd_lm(int ctl, int hdev, char *opt)
557
{
558
struct hci_dev_req dr;
559
560
dr.dev_id = hdev;
561
562
if (hci_strtolm(opt, &dr.dev_opt)) {
563
if (ioctl(ctl, HCISETLINKMODE, (unsigned long) &dr) < 0) {
564
fprintf(stderr, "Can't set default link mode on hci%d: %s (%d)\n",
565
hdev, strerror(errno), errno);
566
exit(1);
567
}
568
} else {
569
print_dev_hdr(&di);
570
print_link_mode(&di);
571
}
572
}
573
574
static void cmd_aclmtu(int ctl, int hdev, char *opt)
575
{
576
struct hci_dev_req dr = { .dev_id = hdev };
577
uint16_t mtu, mpkt;
578
579
if (!opt)
580
return;
581
582
if (sscanf(opt, "%4hu:%4hu", &mtu, &mpkt) != 2)
583
return;
584
585
dr.dev_opt = htobl(htobs(mpkt) | (htobs(mtu) << 16));
586
587
if (ioctl(ctl, HCISETACLMTU, (unsigned long) &dr) < 0) {
588
fprintf(stderr, "Can't set ACL mtu on hci%d: %s(%d)\n",
589
hdev, strerror(errno), errno);
590
exit(1);
591
}
592
}
593
594
static void cmd_scomtu(int ctl, int hdev, char *opt)
595
{
596
struct hci_dev_req dr = { .dev_id = hdev };
597
uint16_t mtu, mpkt;
598
599
if (!opt)
600
return;
601
602
if (sscanf(opt, "%4hu:%4hu", &mtu, &mpkt) != 2)
603
return;
604
605
dr.dev_opt = htobl(htobs(mpkt) | (htobs(mtu) << 16));
606
607
if (ioctl(ctl, HCISETSCOMTU, (unsigned long) &dr) < 0) {
608
fprintf(stderr, "Can't set SCO mtu on hci%d: %s (%d)\n",
609
hdev, strerror(errno), errno);
610
exit(1);
611
}
612
}
613
614
static void cmd_features(int ctl, int hdev, char *opt)
615
{
616
uint8_t features[8], max_page = 0;
617
char *tmp;
618
int i, dd;
619
620
if (!(di.features[7] & LMP_EXT_FEAT)) {
621
print_dev_hdr(&di);
622
print_dev_features(&di, 1);
623
return;
624
}
625
626
dd = hci_open_dev(hdev);
627
if (dd < 0) {
628
fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
629
hdev, strerror(errno), errno);
630
exit(1);
631
}
632
633
if (hci_read_local_ext_features(dd, 0, &max_page, features, 1000) < 0) {
634
fprintf(stderr, "Can't read extended features hci%d: %s (%d)\n",
635
hdev, strerror(errno), errno);
636
exit(1);
637
}
638
639
print_dev_hdr(&di);
640
printf("\tFeatures%s: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
641
"0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n",
642
(max_page > 0) ? " page 0" : "",
643
features[0], features[1], features[2], features[3],
644
features[4], features[5], features[6], features[7]);
645
646
tmp = lmp_featurestostr(di.features, "\t\t", 63);
647
printf("%s\n", tmp);
648
bt_free(tmp);
649
650
for (i = 1; i <= max_page; i++) {
651
if (hci_read_local_ext_features(dd, i, NULL,
652
features, 1000) < 0)
653
continue;
654
655
printf("\tFeatures page %d: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
656
"0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", i,
657
features[0], features[1], features[2], features[3],
658
features[4], features[5], features[6], features[7]);
659
}
660
661
hci_close_dev(dd);
662
}
663
664
static void cmd_name(int ctl, int hdev, char *opt)
665
{
666
int dd;
667
668
dd = hci_open_dev(hdev);
669
if (dd < 0) {
670
fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
671
hdev, strerror(errno), errno);
672
exit(1);
673
}
674
675
if (opt) {
676
if (hci_write_local_name(dd, opt, 2000) < 0) {
677
fprintf(stderr, "Can't change local name on hci%d: %s (%d)\n",
678
hdev, strerror(errno), errno);
679
exit(1);
680
}
681
} else {
682
char name[249];
683
int i;
684
685
if (hci_read_local_name(dd, sizeof(name), name, 1000) < 0) {
686
fprintf(stderr, "Can't read local name on hci%d: %s (%d)\n",
687
hdev, strerror(errno), errno);
688
exit(1);
689
}
690
691
for (i = 0; i < 248 && name[i]; i++) {
692
if ((unsigned char) name[i] < 32 || name[i] == 127)
693
name[i] = '.';
694
}
695
696
name[248] = '\0';
697
698
print_dev_hdr(&di);
699
printf("\tName: '%s'\n", name);
700
}
701
702
hci_close_dev(dd);
703
}
704
705
/*
706
* see http://www.bluetooth.org/assigned-numbers/baseband.htm --- all
707
* strings are reproduced verbatim
708
*/
709
static char *get_minor_device_name(int major, int minor)
710
{
711
switch (major) {
712
case 0: /* misc */
713
return "";
714
case 1: /* computer */
715
switch (minor) {
716
case 0:
717
return "Uncategorized";
718
case 1:
719
return "Desktop workstation";
720
case 2:
721
return "Server";
722
case 3:
723
return "Laptop";
724
case 4:
725
return "Handheld";
726
case 5:
727
return "Palm";
728
case 6:
729
return "Wearable";
730
}
731
break;
732
case 2: /* phone */
733
switch (minor) {
734
case 0:
735
return "Uncategorized";
736
case 1:
737
return "Cellular";
738
case 2:
739
return "Cordless";
740
case 3:
741
return "Smart phone";
742
case 4:
743
return "Wired modem or voice gateway";
744
case 5:
745
return "Common ISDN Access";
746
case 6:
747
return "Sim Card Reader";
748
}
749
break;
750
case 3: /* lan access */
751
if (minor == 0)
752
return "Uncategorized";
753
switch (minor / 8) {
754
case 0:
755
return "Fully available";
756
case 1:
757
return "1-17% utilized";
758
case 2:
759
return "17-33% utilized";
760
case 3:
761
return "33-50% utilized";
762
case 4:
763
return "50-67% utilized";
764
case 5:
765
return "67-83% utilized";
766
case 6:
767
return "83-99% utilized";
768
case 7:
769
return "No service available";
770
}
771
break;
772
case 4: /* audio/video */
773
switch (minor) {
774
case 0:
775
return "Uncategorized";
776
case 1:
777
return "Device conforms to the Headset profile";
778
case 2:
779
return "Hands-free";
780
/* 3 is reserved */
781
case 4:
782
return "Microphone";
783
case 5:
784
return "Loudspeaker";
785
case 6:
786
return "Headphones";
787
case 7:
788
return "Portable Audio";
789
case 8:
790
return "Car Audio";
791
case 9:
792
return "Set-top box";
793
case 10:
794
return "HiFi Audio Device";
795
case 11:
796
return "VCR";
797
case 12:
798
return "Video Camera";
799
case 13:
800
return "Camcorder";
801
case 14:
802
return "Video Monitor";
803
case 15:
804
return "Video Display and Loudspeaker";
805
case 16:
806
return "Video Conferencing";
807
/* 17 is reserved */
808
case 18:
809
return "Gaming/Toy";
810
}
811
break;
812
case 5: /* peripheral */ {
813
static char cls_str[48];
814
815
cls_str[0] = '\0';
816
817
switch (minor & 48) {
818
case 16:
819
strncpy(cls_str, "Keyboard", sizeof(cls_str));
820
break;
821
case 32:
822
strncpy(cls_str, "Pointing device", sizeof(cls_str));
823
break;
824
case 48:
825
strncpy(cls_str, "Combo keyboard/pointing device", sizeof(cls_str));
826
break;
827
}
828
if ((minor & 15) && (strlen(cls_str) > 0))
829
strcat(cls_str, "/");
830
831
switch (minor & 15) {
832
case 0:
833
break;
834
case 1:
835
strncat(cls_str, "Joystick", sizeof(cls_str) - strlen(cls_str));
836
break;
837
case 2:
838
strncat(cls_str, "Gamepad", sizeof(cls_str) - strlen(cls_str));
839
break;
840
case 3:
841
strncat(cls_str, "Remote control", sizeof(cls_str) - strlen(cls_str));
842
break;
843
case 4:
844
strncat(cls_str, "Sensing device", sizeof(cls_str) - strlen(cls_str));
845
break;
846
case 5:
847
strncat(cls_str, "Digitizer tablet", sizeof(cls_str) - strlen(cls_str));
848
break;
849
case 6:
850
strncat(cls_str, "Card reader", sizeof(cls_str) - strlen(cls_str));
851
break;
852
default:
853
strncat(cls_str, "(reserved)", sizeof(cls_str) - strlen(cls_str));
854
break;
855
}
856
if (strlen(cls_str) > 0)
857
return cls_str;
858
}
859
case 6: /* imaging */
860
if (minor & 4)
861
return "Display";
862
if (minor & 8)
863
return "Camera";
864
if (minor & 16)
865
return "Scanner";
866
if (minor & 32)
867
return "Printer";
868
break;
869
case 7: /* wearable */
870
switch (minor) {
871
case 1:
872
return "Wrist Watch";
873
case 2:
874
return "Pager";
875
case 3:
876
return "Jacket";
877
case 4:
878
return "Helmet";
879
case 5:
880
return "Glasses";
881
}
882
break;
883
case 8: /* toy */
884
switch (minor) {
885
case 1:
886
return "Robot";
887
case 2:
888
return "Vehicle";
889
case 3:
890
return "Doll / Action Figure";
891
case 4:
892
return "Controller";
893
case 5:
894
return "Game";
895
}
896
break;
897
case 63: /* uncategorised */
898
return "";
899
}
900
return "Unknown (reserved) minor device class";
901
}
902
903
static void cmd_class(int ctl, int hdev, char *opt)
904
{
905
static const char *services[] = { "Positioning",
906
"Networking",
907
"Rendering",
908
"Capturing",
909
"Object Transfer",
910
"Audio",
911
"Telephony",
912
"Information" };
913
static const char *major_devices[] = { "Miscellaneous",
914
"Computer",
915
"Phone",
916
"LAN Access",
917
"Audio/Video",
918
"Peripheral",
919
"Imaging",
920
"Uncategorized" };
921
int s = hci_open_dev(hdev);
922
923
if (s < 0) {
924
fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
925
hdev, strerror(errno), errno);
926
exit(1);
927
}
928
if (opt) {
929
uint32_t cod = strtoul(opt, NULL, 16);
930
if (hci_write_class_of_dev(s, cod, 2000) < 0) {
931
fprintf(stderr, "Can't write local class of device on hci%d: %s (%d)\n",
932
hdev, strerror(errno), errno);
933
exit(1);
934
}
935
} else {
936
uint8_t cls[3];
937
if (hci_read_class_of_dev(s, cls, 1000) < 0) {
938
fprintf(stderr, "Can't read class of device on hci%d: %s (%d)\n",
939
hdev, strerror(errno), errno);
940
exit(1);
941
}
942
print_dev_hdr(&di);
943
printf("\tClass: 0x%02x%02x%02x\n", cls[2], cls[1], cls[0]);
944
printf("\tService Classes: ");
945
if (cls[2]) {
946
unsigned int i;
947
int first = 1;
948
for (i = 0; i < (sizeof(services) / sizeof(*services)); i++)
949
if (cls[2] & (1 << i)) {
950
if (!first)
951
printf(", ");
952
printf("%s", services[i]);
953
first = 0;
954
}
955
} else
956
printf("Unspecified");
957
printf("\n\tDevice Class: ");
958
if ((cls[1] & 0x1f) >= sizeof(major_devices) / sizeof(*major_devices))
959
printf("Invalid Device Class!\n");
960
else
961
printf("%s, %s\n", major_devices[cls[1] & 0x1f],
962
get_minor_device_name(cls[1] & 0x1f, cls[0] >> 2));
963
}
964
}
965
966
static void cmd_voice(int ctl, int hdev, char *opt)
967
{
968
static char *icf[] = { "Linear",
969
"u-Law",
970
"A-Law",
971
"Reserved" };
972
973
static char *idf[] = { "1's complement",
974
"2's complement",
975
"Sign-Magnitude",
976
"Reserved" };
977
978
static char *iss[] = { "8 bit",
979
"16 bit" };
980
981
static char *acf[] = { "CVSD",
982
"u-Law",
983
"A-Law",
984
"Reserved" };
985
986
int s = hci_open_dev(hdev);
987
988
if (s < 0) {
989
fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
990
hdev, strerror(errno), errno);
991
exit(1);
992
}
993
if (opt) {
994
uint16_t vs = htobs(strtoul(opt, NULL, 16));
995
if (hci_write_voice_setting(s, vs, 2000) < 0) {
996
fprintf(stderr, "Can't write voice setting on hci%d: %s (%d)\n",
997
hdev, strerror(errno), errno);
998
exit(1);
999
}
1000
} else {
1001
uint16_t vs;
1002
uint8_t ic;
1003
if (hci_read_voice_setting(s, &vs, 1000) < 0) {
1004
fprintf(stderr, "Can't read voice setting on hci%d: %s (%d)\n",
1005
hdev, strerror(errno), errno);
1006
exit(1);
1007
}
1008
vs = htobs(vs);
1009
ic = (vs & 0x0300) >> 8;
1010
print_dev_hdr(&di);
1011
printf("\tVoice setting: 0x%04x%s\n", vs,
1012
((vs & 0x03fc) == 0x0060) ? " (Default Condition)" : "");
1013
printf("\tInput Coding: %s\n", icf[ic]);
1014
printf("\tInput Data Format: %s\n", idf[(vs & 0xc0) >> 6]);
1015
1016
if (!ic) {
1017
printf("\tInput Sample Size: %s\n",
1018
iss[(vs & 0x20) >> 5]);
1019
printf("\t# of bits padding at MSB: %d\n",
1020
(vs & 0x1c) >> 2);
1021
}
1022
printf("\tAir Coding Format: %s\n", acf[vs & 0x03]);
1023
}
1024
}
1025
1026
static void cmd_delkey(int ctl, int hdev, char *opt)
1027
{
1028
bdaddr_t bdaddr;
1029
uint8_t all;
1030
int dd;
1031
1032
if (!opt)
1033
return;
1034
1035
dd = hci_open_dev(hdev);
1036
if (dd < 0) {
1037
fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
1038
hdev, strerror(errno), errno);
1039
exit(1);
1040
}
1041
1042
if (!strcasecmp(opt, "all")) {
1043
bacpy(&bdaddr, BDADDR_ANY);
1044
all = 1;
1045
} else {
1046
str2ba(opt, &bdaddr);
1047
all = 0;
1048
}
1049
1050
if (hci_delete_stored_link_key(dd, &bdaddr, all, 1000) < 0) {
1051
fprintf(stderr, "Can't delete stored link key on hci%d: %s (%d)\n",
1052
hdev, strerror(errno), errno);
1053
exit(1);
1054
}
1055
1056
hci_close_dev(dd);
1057
}
1058
1059
static void cmd_oob_data(int ctl, int hdev, char *opt)
1060
{
1061
uint8_t hash[16], randomizer[16];
1062
int i, dd;
1063
1064
dd = hci_open_dev(hdev);
1065
if (dd < 0) {
1066
fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
1067
hdev, strerror(errno), errno);
1068
exit(1);
1069
}
1070
1071
if (hci_read_local_oob_data(dd, hash, randomizer, 1000) < 0) {
1072
fprintf(stderr, "Can't read local OOB data on hci%d: %s (%d)\n",
1073
hdev, strerror(errno), errno);
1074
exit(1);
1075
}
1076
1077
print_dev_hdr(&di);
1078
printf("\tOOB Hash: ");
1079
for (i = 0; i < 16; i++)
1080
printf(" %02x", hash[i]);
1081
printf("\n\tRandomizer:");
1082
for (i = 0; i < 16; i++)
1083
printf(" %02x", randomizer[i]);
1084
printf("\n");
1085
1086
hci_close_dev(dd);
1087
}
1088
1089
static void cmd_commands(int ctl, int hdev, char *opt)
1090
{
1091
uint8_t cmds[64];
1092
char *str;
1093
int i, n, dd;
1094
1095
dd = hci_open_dev(hdev);
1096
if (dd < 0) {
1097
fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
1098
hdev, strerror(errno), errno);
1099
exit(1);
1100
}
1101
1102
if (hci_read_local_commands(dd, cmds, 1000) < 0) {
1103
fprintf(stderr, "Can't read support commands on hci%d: %s (%d)\n",
1104
hdev, strerror(errno), errno);
1105
exit(1);
1106
}
1107
1108
print_dev_hdr(&di);
1109
for (i = 0; i < 64; i++) {
1110
if (!cmds[i])
1111
continue;
1112
1113
printf("%s Octet %-2d = 0x%02x (Bit",
1114
i ? "\t\t ": "\tCommands:", i, cmds[i]);
1115
for (n = 0; n < 8; n++)
1116
if (cmds[i] & (1 << n))
1117
printf(" %d", n);
1118
printf(")\n");
1119
}
1120
1121
str = hci_commandstostr(cmds, "\t", 71);
1122
printf("%s\n", str);
1123
bt_free(str);
1124
1125
hci_close_dev(dd);
1126
}
1127
1128
static void cmd_version(int ctl, int hdev, char *opt)
1129
{
1130
struct hci_version ver;
1131
char *hciver, *lmpver;
1132
int dd;
1133
1134
dd = hci_open_dev(hdev);
1135
if (dd < 0) {
1136
fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
1137
hdev, strerror(errno), errno);
1138
exit(1);
1139
}
1140
1141
if (hci_read_local_version(dd, &ver, 1000) < 0) {
1142
fprintf(stderr, "Can't read version info hci%d: %s (%d)\n",
1143
hdev, strerror(errno), errno);
1144
exit(1);
1145
}
1146
1147
hciver = hci_vertostr(ver.hci_ver);
1148
if (((di.type & 0x30) >> 4) == HCI_BREDR)
1149
lmpver = lmp_vertostr(ver.lmp_ver);
1150
else
1151
lmpver = pal_vertostr(ver.lmp_ver);
1152
1153
print_dev_hdr(&di);
1154
printf("\tHCI Version: %s (0x%x) Revision: 0x%x\n"
1155
"\t%s Version: %s (0x%x) Subversion: 0x%x\n"
1156
"\tManufacturer: %s (%d)\n",
1157
hciver ? hciver : "n/a", ver.hci_ver, ver.hci_rev,
1158
(((di.type & 0x30) >> 4) == HCI_BREDR) ? "LMP" : "PAL",
1159
lmpver ? lmpver : "n/a", ver.lmp_ver, ver.lmp_subver,
1160
bt_compidtostr(ver.manufacturer), ver.manufacturer);
1161
1162
if (hciver)
1163
bt_free(hciver);
1164
if (lmpver)
1165
bt_free(lmpver);
1166
1167
hci_close_dev(dd);
1168
}
1169
1170
static void cmd_inq_tpl(int ctl, int hdev, char *opt)
1171
{
1172
int dd;
1173
1174
dd = hci_open_dev(hdev);
1175
if (dd < 0) {
1176
fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
1177
hdev, strerror(errno), errno);
1178
exit(1);
1179
}
1180
1181
if (opt) {
1182
int8_t level = atoi(opt);
1183
1184
if (hci_write_inquiry_transmit_power_level(dd, level, 2000) < 0) {
1185
fprintf(stderr, "Can't set inquiry transmit power level on hci%d: %s (%d)\n",
1186
hdev, strerror(errno), errno);
1187
exit(1);
1188
}
1189
} else {
1190
int8_t level;
1191
1192
if (hci_read_inq_response_tx_power_level(dd, &level, 1000) < 0) {
1193
fprintf(stderr, "Can't read inquiry transmit power level on hci%d: %s (%d)\n",
1194
hdev, strerror(errno), errno);
1195
exit(1);
1196
}
1197
1198
print_dev_hdr(&di);
1199
printf("\tInquiry transmit power level: %d\n", level);
1200
}
1201
1202
hci_close_dev(dd);
1203
}
1204
1205
static void cmd_inq_mode(int ctl, int hdev, char *opt)
1206
{
1207
int dd;
1208
1209
dd = hci_open_dev(hdev);
1210
if (dd < 0) {
1211
fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
1212
hdev, strerror(errno), errno);
1213
exit(1);
1214
}
1215
1216
if (opt) {
1217
uint8_t mode = atoi(opt);
1218
1219
if (hci_write_inquiry_mode(dd, mode, 2000) < 0) {
1220
fprintf(stderr, "Can't set inquiry mode on hci%d: %s (%d)\n",
1221
hdev, strerror(errno), errno);
1222
exit(1);
1223
}
1224
} else {
1225
uint8_t mode;
1226
1227
if (hci_read_inquiry_mode(dd, &mode, 1000) < 0) {
1228
fprintf(stderr, "Can't read inquiry mode on hci%d: %s (%d)\n",
1229
hdev, strerror(errno), errno);
1230
exit(1);
1231
}
1232
1233
print_dev_hdr(&di);
1234
printf("\tInquiry mode: ");
1235
switch (mode) {
1236
case 0:
1237
printf("Standard Inquiry\n");
1238
break;
1239
case 1:
1240
printf("Inquiry with RSSI\n");
1241
break;
1242
case 2:
1243
printf("Inquiry with RSSI or Extended Inquiry\n");
1244
break;
1245
default:
1246
printf("Unknown (0x%02x)\n", mode);
1247
break;
1248
}
1249
}
1250
1251
hci_close_dev(dd);
1252
}
1253
1254
static void cmd_inq_data(int ctl, int hdev, char *opt)
1255
{
1256
int i, dd;
1257
1258
dd = hci_open_dev(hdev);
1259
if (dd < 0) {
1260
fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
1261
hdev, strerror(errno), errno);
1262
exit(1);
1263
}
1264
1265
if (opt) {
1266
uint8_t fec = 0, data[HCI_MAX_EIR_LENGTH];
1267
char tmp[3];
1268
int i, size;
1269
1270
memset(data, 0, sizeof(data));
1271
1272
memset(tmp, 0, sizeof(tmp));
1273
size = (strlen(opt) + 1) / 2;
1274
if (size > HCI_MAX_EIR_LENGTH)
1275
size = HCI_MAX_EIR_LENGTH;
1276
1277
for (i = 0; i < size; i++) {
1278
memcpy(tmp, opt + (i * 2), 2);
1279
data[i] = strtol(tmp, NULL, 16);
1280
}
1281
1282
if (hci_write_ext_inquiry_response(dd, fec, data, 2000) < 0) {
1283
fprintf(stderr, "Can't set extended inquiry response on hci%d: %s (%d)\n",
1284
hdev, strerror(errno), errno);
1285
exit(1);
1286
}
1287
} else {
1288
uint8_t fec, data[HCI_MAX_EIR_LENGTH], len, type, *ptr;
1289
char *str;
1290
1291
if (hci_read_ext_inquiry_response(dd, &fec, data, 1000) < 0) {
1292
fprintf(stderr, "Can't read extended inquiry response on hci%d: %s (%d)\n",
1293
hdev, strerror(errno), errno);
1294
exit(1);
1295
}
1296
1297
print_dev_hdr(&di);
1298
printf("\tFEC %s\n\t\t", fec ? "enabled" : "disabled");
1299
for (i = 0; i < HCI_MAX_EIR_LENGTH; i++)
1300
printf("%02x%s%s", data[i], (i + 1) % 8 ? "" : " ",
1301
(i + 1) % 16 ? " " : (i < 239 ? "\n\t\t" : "\n"));
1302
1303
ptr = data;
1304
while (*ptr) {
1305
len = *ptr++;
1306
type = *ptr++;
1307
switch (type) {
1308
case 0x01:
1309
printf("\tFlags:");
1310
for (i = 0; i < len - 1; i++)
1311
printf(" 0x%2.2x", *((uint8_t *) (ptr + i)));
1312
printf("\n");
1313
break;
1314
case 0x02:
1315
case 0x03:
1316
printf("\t%s service classes:",
1317
type == 0x02 ? "Shortened" : "Complete");
1318
for (i = 0; i < (len - 1) / 2; i++) {
1319
uint16_t val = bt_get_le16((ptr + (i * 2)));
1320
printf(" 0x%4.4x", val);
1321
}
1322
printf("\n");
1323
break;
1324
case 0x08:
1325
case 0x09:
1326
str = malloc(len);
1327
if (str) {
1328
snprintf(str, len, "%s", ptr);
1329
for (i = 0; i < len - 1; i++) {
1330
if ((unsigned char) str[i] < 32 || str[i] == 127)
1331
str[i] = '.';
1332
}
1333
printf("\t%s local name: \'%s\'\n",
1334
type == 0x08 ? "Shortened" : "Complete", str);
1335
free(str);
1336
}
1337
break;
1338
case 0x0a:
1339
printf("\tTX power level: %d\n", *((int8_t *) ptr));
1340
break;
1341
case 0x10:
1342
printf("\tDevice ID with %d bytes data\n",
1343
len - 1);
1344
break;
1345
default:
1346
printf("\tUnknown type 0x%02x with %d bytes data\n",
1347
type, len - 1);
1348
break;
1349
}
1350
1351
ptr += (len - 1);
1352
}
1353
1354
printf("\n");
1355
}
1356
1357
hci_close_dev(dd);
1358
}
1359
1360
static void cmd_inq_type(int ctl, int hdev, char *opt)
1361
{
1362
int dd;
1363
1364
dd = hci_open_dev(hdev);
1365
if (dd < 0) {
1366
fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
1367
hdev, strerror(errno), errno);
1368
exit(1);
1369
}
1370
1371
if (opt) {
1372
uint8_t type = atoi(opt);
1373
1374
if (hci_write_inquiry_scan_type(dd, type, 2000) < 0) {
1375
fprintf(stderr, "Can't set inquiry scan type on hci%d: %s (%d)\n",
1376
hdev, strerror(errno), errno);
1377
exit(1);
1378
}
1379
} else {
1380
uint8_t type;
1381
1382
if (hci_read_inquiry_scan_type(dd, &type, 1000) < 0) {
1383
fprintf(stderr, "Can't read inquiry scan type on hci%d: %s (%d)\n",
1384
hdev, strerror(errno), errno);
1385
exit(1);
1386
}
1387
1388
print_dev_hdr(&di);
1389
printf("\tInquiry scan type: %s\n",
1390
type == 1 ? "Interlaced Inquiry Scan" : "Standard Inquiry Scan");
1391
}
1392
1393
hci_close_dev(dd);
1394
}
1395
1396
static void cmd_inq_parms(int ctl, int hdev, char *opt)
1397
{
1398
struct hci_request rq;
1399
int s;
1400
1401
if ((s = hci_open_dev(hdev)) < 0) {
1402
fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
1403
hdev, strerror(errno), errno);
1404
exit(1);
1405
}
1406
1407
memset(&rq, 0, sizeof(rq));
1408
1409
if (opt) {
1410
unsigned int window, interval;
1411
write_inq_activity_cp cp;
1412
1413
if (sscanf(opt,"%4u:%4u", &window, &interval) != 2) {
1414
printf("Invalid argument format\n");
1415
exit(1);
1416
}
1417
1418
rq.ogf = OGF_HOST_CTL;
1419
rq.ocf = OCF_WRITE_INQ_ACTIVITY;
1420
rq.cparam = &cp;
1421
rq.clen = WRITE_INQ_ACTIVITY_CP_SIZE;
1422
1423
cp.window = htobs((uint16_t) window);
1424
cp.interval = htobs((uint16_t) interval);
1425
1426
if (window < 0x12 || window > 0x1000)
1427
printf("Warning: inquiry window out of range!\n");
1428
1429
if (interval < 0x12 || interval > 0x1000)
1430
printf("Warning: inquiry interval out of range!\n");
1431
1432
if (hci_send_req(s, &rq, 2000) < 0) {
1433
fprintf(stderr, "Can't set inquiry parameters name on hci%d: %s (%d)\n",
1434
hdev, strerror(errno), errno);
1435
exit(1);
1436
}
1437
} else {
1438
uint16_t window, interval;
1439
read_inq_activity_rp rp;
1440
1441
rq.ogf = OGF_HOST_CTL;
1442
rq.ocf = OCF_READ_INQ_ACTIVITY;
1443
rq.rparam = &rp;
1444
rq.rlen = READ_INQ_ACTIVITY_RP_SIZE;
1445
1446
if (hci_send_req(s, &rq, 1000) < 0) {
1447
fprintf(stderr, "Can't read inquiry parameters on hci%d: %s (%d)\n",
1448
hdev, strerror(errno), errno);
1449
exit(1);
1450
}
1451
if (rp.status) {
1452
printf("Read inquiry parameters on hci%d returned status %d\n",
1453
hdev, rp.status);
1454
exit(1);
1455
}
1456
print_dev_hdr(&di);
1457
1458
window = btohs(rp.window);
1459
interval = btohs(rp.interval);
1460
printf("\tInquiry interval: %u slots (%.2f ms), window: %u slots (%.2f ms)\n",
1461
interval, (float)interval * 0.625, window, (float)window * 0.625);
1462
}
1463
}
1464
1465
static void cmd_page_parms(int ctl, int hdev, char *opt)
1466
{
1467
struct hci_request rq;
1468
int s;
1469
1470
if ((s = hci_open_dev(hdev)) < 0) {
1471
fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
1472
hdev, strerror(errno), errno);
1473
exit(1);
1474
}
1475
1476
memset(&rq, 0, sizeof(rq));
1477
1478
if (opt) {
1479
unsigned int window, interval;
1480
write_page_activity_cp cp;
1481
1482
if (sscanf(opt,"%4u:%4u", &window, &interval) != 2) {
1483
printf("Invalid argument format\n");
1484
exit(1);
1485
}
1486
1487
rq.ogf = OGF_HOST_CTL;
1488
rq.ocf = OCF_WRITE_PAGE_ACTIVITY;
1489
rq.cparam = &cp;
1490
rq.clen = WRITE_PAGE_ACTIVITY_CP_SIZE;
1491
1492
cp.window = htobs((uint16_t) window);
1493
cp.interval = htobs((uint16_t) interval);
1494
1495
if (window < 0x12 || window > 0x1000)
1496
printf("Warning: page window out of range!\n");
1497
1498
if (interval < 0x12 || interval > 0x1000)
1499
printf("Warning: page interval out of range!\n");
1500
1501
if (hci_send_req(s, &rq, 2000) < 0) {
1502
fprintf(stderr, "Can't set page parameters name on hci%d: %s (%d)\n",
1503
hdev, strerror(errno), errno);
1504
exit(1);
1505
}
1506
} else {
1507
uint16_t window, interval;
1508
read_page_activity_rp rp;
1509
1510
rq.ogf = OGF_HOST_CTL;
1511
rq.ocf = OCF_READ_PAGE_ACTIVITY;
1512
rq.rparam = &rp;
1513
rq.rlen = READ_PAGE_ACTIVITY_RP_SIZE;
1514
1515
if (hci_send_req(s, &rq, 1000) < 0) {
1516
fprintf(stderr, "Can't read page parameters on hci%d: %s (%d)\n",
1517
hdev, strerror(errno), errno);
1518
exit(1);
1519
}
1520
if (rp.status) {
1521
printf("Read page parameters on hci%d returned status %d\n",
1522
hdev, rp.status);
1523
exit(1);
1524
}
1525
print_dev_hdr(&di);
1526
1527
window = btohs(rp.window);
1528
interval = btohs(rp.interval);
1529
printf("\tPage interval: %u slots (%.2f ms), "
1530
"window: %u slots (%.2f ms)\n",
1531
interval, (float)interval * 0.625,
1532
window, (float)window * 0.625);
1533
}
1534
}
1535
1536
static void cmd_page_to(int ctl, int hdev, char *opt)
1537
{
1538
struct hci_request rq;
1539
int s;
1540
1541
if ((s = hci_open_dev(hdev)) < 0) {
1542
fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
1543
hdev, strerror(errno), errno);
1544
exit(1);
1545
}
1546
1547
memset(&rq, 0, sizeof(rq));
1548
1549
if (opt) {
1550
unsigned int timeout;
1551
write_page_timeout_cp cp;
1552
1553
if (sscanf(opt,"%5u", &timeout) != 1) {
1554
printf("Invalid argument format\n");
1555
exit(1);
1556
}
1557
1558
rq.ogf = OGF_HOST_CTL;
1559
rq.ocf = OCF_WRITE_PAGE_TIMEOUT;
1560
rq.cparam = &cp;
1561
rq.clen = WRITE_PAGE_TIMEOUT_CP_SIZE;
1562
1563
cp.timeout = htobs((uint16_t) timeout);
1564
1565
if (timeout < 0x01 || timeout > 0xFFFF)
1566
printf("Warning: page timeout out of range!\n");
1567
1568
if (hci_send_req(s, &rq, 2000) < 0) {
1569
fprintf(stderr, "Can't set page timeout on hci%d: %s (%d)\n",
1570
hdev, strerror(errno), errno);
1571
exit(1);
1572
}
1573
} else {
1574
uint16_t timeout;
1575
read_page_timeout_rp rp;
1576
1577
rq.ogf = OGF_HOST_CTL;
1578
rq.ocf = OCF_READ_PAGE_TIMEOUT;
1579
rq.rparam = &rp;
1580
rq.rlen = READ_PAGE_TIMEOUT_RP_SIZE;
1581
1582
if (hci_send_req(s, &rq, 1000) < 0) {
1583
fprintf(stderr, "Can't read page timeout on hci%d: %s (%d)\n",
1584
hdev, strerror(errno), errno);
1585
exit(1);
1586
}
1587
if (rp.status) {
1588
printf("Read page timeout on hci%d returned status %d\n",
1589
hdev, rp.status);
1590
exit(1);
1591
}
1592
print_dev_hdr(&di);
1593
1594
timeout = btohs(rp.timeout);
1595
printf("\tPage timeout: %u slots (%.2f ms)\n",
1596
timeout, (float)timeout * 0.625);
1597
}
1598
}
1599
1600
static void cmd_afh_mode(int ctl, int hdev, char *opt)
1601
{
1602
int dd;
1603
1604
dd = hci_open_dev(hdev);
1605
if (dd < 0) {
1606
fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
1607
hdev, strerror(errno), errno);
1608
exit(1);
1609
}
1610
1611
if (opt) {
1612
uint8_t mode = atoi(opt);
1613
1614
if (hci_write_afh_mode(dd, mode, 2000) < 0) {
1615
fprintf(stderr, "Can't set AFH mode on hci%d: %s (%d)\n",
1616
hdev, strerror(errno), errno);
1617
exit(1);
1618
}
1619
} else {
1620
uint8_t mode;
1621
1622
if (hci_read_afh_mode(dd, &mode, 1000) < 0) {
1623
fprintf(stderr, "Can't read AFH mode on hci%d: %s (%d)\n",
1624
hdev, strerror(errno), errno);
1625
exit(1);
1626
}
1627
1628
print_dev_hdr(&di);
1629
printf("\tAFH mode: %s\n", mode == 1 ? "Enabled" : "Disabled");
1630
}
1631
}
1632
1633
static void cmd_ssp_mode(int ctl, int hdev, char *opt)
1634
{
1635
int dd;
1636
1637
dd = hci_open_dev(hdev);
1638
if (dd < 0) {
1639
fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
1640
hdev, strerror(errno), errno);
1641
exit(1);
1642
}
1643
1644
if (opt) {
1645
uint8_t mode = atoi(opt);
1646
1647
if (hci_write_simple_pairing_mode(dd, mode, 2000) < 0) {
1648
fprintf(stderr, "Can't set Simple Pairing mode on hci%d: %s (%d)\n",
1649
hdev, strerror(errno), errno);
1650
exit(1);
1651
}
1652
} else {
1653
uint8_t mode;
1654
1655
if (hci_read_simple_pairing_mode(dd, &mode, 1000) < 0) {
1656
fprintf(stderr, "Can't read Simple Pairing mode on hci%d: %s (%d)\n",
1657
hdev, strerror(errno), errno);
1658
exit(1);
1659
}
1660
1661
print_dev_hdr(&di);
1662
printf("\tSimple Pairing mode: %s\n",
1663
mode == 1 ? "Enabled" : "Disabled");
1664
}
1665
}
1666
1667
static void print_rev_ericsson(int dd)
1668
{
1669
struct hci_request rq;
1670
unsigned char buf[102];
1671
1672
memset(&rq, 0, sizeof(rq));
1673
rq.ogf = OGF_VENDOR_CMD;
1674
rq.ocf = 0x000f;
1675
rq.cparam = NULL;
1676
rq.clen = 0;
1677
rq.rparam = &buf;
1678
rq.rlen = sizeof(buf);
1679
1680
if (hci_send_req(dd, &rq, 1000) < 0) {
1681
printf("\nCan't read revision info: %s (%d)\n",
1682
strerror(errno), errno);
1683
return;
1684
}
1685
1686
printf("\t%s\n", buf + 1);
1687
}
1688
1689
static void print_rev_csr(int dd, uint16_t rev)
1690
{
1691
uint16_t buildid, chipver, chiprev, maxkeylen, mapsco;
1692
1693
if (csr_read_varid_uint16(dd, 0, CSR_VARID_BUILDID, &buildid) < 0) {
1694
printf("\t%s\n", csr_buildidtostr(rev));
1695
return;
1696
}
1697
1698
printf("\t%s\n", csr_buildidtostr(buildid));
1699
1700
if (!csr_read_varid_uint16(dd, 1, CSR_VARID_CHIPVER, &chipver)) {
1701
if (csr_read_varid_uint16(dd, 2, CSR_VARID_CHIPREV, &chiprev) < 0)
1702
chiprev = 0;
1703
printf("\tChip version: %s\n", csr_chipvertostr(chipver, chiprev));
1704
}
1705
1706
if (!csr_read_varid_uint16(dd, 3, CSR_VARID_MAX_CRYPT_KEY_LENGTH, &maxkeylen))
1707
printf("\tMax key size: %d bit\n", maxkeylen * 8);
1708
1709
if (!csr_read_pskey_uint16(dd, 4, CSR_PSKEY_HOSTIO_MAP_SCO_PCM, 0x0000, &mapsco))
1710
printf("\tSCO mapping: %s\n", mapsco ? "PCM" : "HCI");
1711
}
1712
1713
static void print_rev_digianswer(int dd)
1714
{
1715
struct hci_request rq;
1716
unsigned char req[] = { 0x07 };
1717
unsigned char buf[102];
1718
1719
memset(&rq, 0, sizeof(rq));
1720
rq.ogf = OGF_VENDOR_CMD;
1721
rq.ocf = 0x000e;
1722
rq.cparam = req;
1723
rq.clen = sizeof(req);
1724
rq.rparam = &buf;
1725
rq.rlen = sizeof(buf);
1726
1727
if (hci_send_req(dd, &rq, 1000) < 0) {
1728
printf("\nCan't read revision info: %s (%d)\n",
1729
strerror(errno), errno);
1730
return;
1731
}
1732
1733
printf("\t%s\n", buf + 1);
1734
}
1735
1736
static void print_rev_broadcom(uint16_t hci_rev, uint16_t lmp_subver)
1737
{
1738
printf("\tFirmware %d.%d / %d\n",
1739
hci_rev & 0xff, lmp_subver >> 8, lmp_subver & 0xff);
1740
}
1741
1742
static void print_rev_avm(uint16_t hci_rev, uint16_t lmp_subver)
1743
{
1744
if (lmp_subver == 0x01)
1745
printf("\tFirmware 03.%d.%d\n", hci_rev >> 8, hci_rev & 0xff);
1746
else
1747
printf("\tUnknown type\n");
1748
}
1749
1750
static void cmd_revision(int ctl, int hdev, char *opt)
1751
{
1752
struct hci_version ver;
1753
int dd;
1754
1755
dd = hci_open_dev(hdev);
1756
if (dd < 0) {
1757
fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
1758
hdev, strerror(errno), errno);
1759
return;
1760
}
1761
1762
if (hci_read_local_version(dd, &ver, 1000) < 0) {
1763
fprintf(stderr, "Can't read version info for hci%d: %s (%d)\n",
1764
hdev, strerror(errno), errno);
1765
return;
1766
}
1767
1768
print_dev_hdr(&di);
1769
switch (ver.manufacturer) {
1770
case 0:
1771
case 37:
1772
case 48:
1773
print_rev_ericsson(dd);
1774
break;
1775
case 10:
1776
print_rev_csr(dd, ver.hci_rev);
1777
break;
1778
case 12:
1779
print_rev_digianswer(dd);
1780
break;
1781
case 15:
1782
print_rev_broadcom(ver.hci_rev, ver.lmp_subver);
1783
break;
1784
case 31:
1785
print_rev_avm(ver.hci_rev, ver.lmp_subver);
1786
break;
1787
default:
1788
printf("\tUnsupported manufacturer\n");
1789
break;
1790
}
1791
return;
1792
}
1793
1794
static void cmd_block(int ctl, int hdev, char *opt)
1795
{
1796
bdaddr_t bdaddr;
1797
int dd;
1798
1799
if (!opt)
1800
return;
1801
1802
dd = hci_open_dev(hdev);
1803
if (dd < 0) {
1804
fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
1805
hdev, strerror(errno), errno);
1806
exit(1);
1807
}
1808
1809
str2ba(opt, &bdaddr);
1810
1811
if (ioctl(dd, HCIBLOCKADDR, &bdaddr) < 0) {
1812
perror("ioctl(HCIBLOCKADDR)");
1813
exit(1);
1814
}
1815
1816
hci_close_dev(dd);
1817
}
1818
1819
static void cmd_unblock(int ctl, int hdev, char *opt)
1820
{
1821
bdaddr_t bdaddr;
1822
int dd;
1823
1824
if (!opt)
1825
return;
1826
1827
dd = hci_open_dev(hdev);
1828
if (dd < 0) {
1829
fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
1830
hdev, strerror(errno), errno);
1831
exit(1);
1832
}
1833
1834
if (!strcasecmp(opt, "all"))
1835
bacpy(&bdaddr, BDADDR_ANY);
1836
else
1837
str2ba(opt, &bdaddr);
1838
1839
if (ioctl(dd, HCIUNBLOCKADDR, &bdaddr) < 0) {
1840
perror("ioctl(HCIUNBLOCKADDR)");
1841
exit(1);
1842
}
1843
1844
hci_close_dev(dd);
1845
}
1846
1847
static void print_dev_hdr(struct hci_dev_info *di)
1848
{
1849
static int hdr = -1;
1850
char addr[18];
1851
1852
if (hdr == di->dev_id)
1853
return;
1854
hdr = di->dev_id;
1855
1856
ba2str(&di->bdaddr, addr);
1857
1858
printf("%s:\tType: %s Bus: %s\n", di->name,
1859
hci_typetostr((di->type & 0x30) >> 4),
1860
hci_bustostr(di->type & 0x0f));
1861
printf("\tBD Address: %s ACL MTU: %d:%d SCO MTU: %d:%d\n",
1862
addr, di->acl_mtu, di->acl_pkts,
1863
di->sco_mtu, di->sco_pkts);
1864
}
1865
1866
static void print_dev_info(int ctl, struct hci_dev_info *di)
1867
{
1868
struct hci_dev_stats *st = &di->stat;
1869
char *str;
1870
1871
print_dev_hdr(di);
1872
1873
str = hci_dflagstostr(di->flags);
1874
printf("\t%s\n", str);
1875
bt_free(str);
1876
1877
printf("\tRX bytes:%d acl:%d sco:%d events:%d errors:%d\n",
1878
st->byte_rx, st->acl_rx, st->sco_rx, st->evt_rx, st->err_rx);
1879
1880
printf("\tTX bytes:%d acl:%d sco:%d commands:%d errors:%d\n",
1881
st->byte_tx, st->acl_tx, st->sco_tx, st->cmd_tx, st->err_tx);
1882
1883
if (all && !hci_test_bit(HCI_RAW, &di->flags)) {
1884
print_dev_features(di, 0);
1885
1886
if (((di->type & 0x30) >> 4) == HCI_BREDR) {
1887
print_pkt_type(di);
1888
print_link_policy(di);
1889
print_link_mode(di);
1890
1891
if (hci_test_bit(HCI_UP, &di->flags)) {
1892
cmd_name(ctl, di->dev_id, NULL);
1893
cmd_class(ctl, di->dev_id, NULL);
1894
}
1895
}
1896
1897
if (hci_test_bit(HCI_UP, &di->flags))
1898
cmd_version(ctl, di->dev_id, NULL);
1899
}
1900
1901
printf("\n");
1902
}
1903
1904
static struct {
1905
char *cmd;
1906
void (*func)(int ctl, int hdev, char *opt);
1907
char *opt;
1908
char *doc;
1909
} command[] = {
1910
{ "up", cmd_up, 0, "Open and initialize HCI device" },
1911
{ "down", cmd_down, 0, "Close HCI device" },
1912
{ "reset", cmd_reset, 0, "Reset HCI device" },
1913
{ "rstat", cmd_rstat, 0, "Reset statistic counters" },
1914
{ "auth", cmd_auth, 0, "Enable Authentication" },
1915
{ "noauth", cmd_auth, 0, "Disable Authentication" },
1916
{ "encrypt", cmd_encrypt, 0, "Enable Encryption" },
1917
{ "noencrypt", cmd_encrypt, 0, "Disable Encryption" },
1918
{ "piscan", cmd_scan, 0, "Enable Page and Inquiry scan" },
1919
{ "noscan", cmd_scan, 0, "Disable scan" },
1920
{ "iscan", cmd_scan, 0, "Enable Inquiry scan" },
1921
{ "pscan", cmd_scan, 0, "Enable Page scan" },
1922
{ "ptype", cmd_ptype, "[type]", "Get/Set default packet type" },
1923
{ "lm", cmd_lm, "[mode]", "Get/Set default link mode" },
1924
{ "lp", cmd_lp, "[policy]", "Get/Set default link policy" },
1925
{ "name", cmd_name, "[name]", "Get/Set local name" },
1926
{ "class", cmd_class, "[class]", "Get/Set class of device" },
1927
{ "voice", cmd_voice, "[voice]", "Get/Set voice setting" },
1928
{ "iac", cmd_iac, "[iac]", "Get/Set inquiry access code" },
1929
{ "inqtpl", cmd_inq_tpl, "[level]", "Get/Set inquiry transmit power level" },
1930
{ "inqmode", cmd_inq_mode, "[mode]", "Get/Set inquiry mode" },
1931
{ "inqdata", cmd_inq_data, "[data]", "Get/Set inquiry data" },
1932
{ "inqtype", cmd_inq_type, "[type]", "Get/Set inquiry scan type" },
1933
{ "inqparms", cmd_inq_parms, "[win:int]", "Get/Set inquiry scan window and interval" },
1934
{ "pageparms", cmd_page_parms, "[win:int]", "Get/Set page scan window and interval" },
1935
{ "pageto", cmd_page_to, "[to]", "Get/Set page timeout" },
1936
{ "afhmode", cmd_afh_mode, "[mode]", "Get/Set AFH mode" },
1937
{ "sspmode", cmd_ssp_mode, "[mode]", "Get/Set Simple Pairing Mode" },
1938
{ "aclmtu", cmd_aclmtu, "<mtu:pkt>", "Set ACL MTU and number of packets" },
1939
{ "scomtu", cmd_scomtu, "<mtu:pkt>", "Set SCO MTU and number of packets" },
1940
{ "delkey", cmd_delkey, "<bdaddr>", "Delete link key from the device" },
1941
{ "oobdata", cmd_oob_data, 0, "Get local OOB data" },
1942
{ "commands", cmd_commands, 0, "Display supported commands" },
1943
{ "features", cmd_features, 0, "Display device features" },
1944
{ "version", cmd_version, 0, "Display version information" },
1945
{ "revision", cmd_revision, 0, "Display revision information" },
1946
{ "block", cmd_block, "<bdaddr>", "Add a device to the blacklist" },
1947
{ "unblock", cmd_unblock, "<bdaddr>", "Remove a device from the blacklist" },
1948
{ "lerandaddr", cmd_le_addr, "<bdaddr>", "Set LE Random Address" },
1949
{ "leadv", cmd_le_adv, "[type]", "Enable LE advertising"
1950
"\n\t\t\t0 - Connectable undirected advertising (default)"
1951
"\n\t\t\t3 - Non connectable undirected advertising"},
1952
{ "noleadv", cmd_no_le_adv, 0, "Disable LE advertising" },
1953
{ "lestates", cmd_le_states, 0, "Display the supported LE states" },
1954
{ NULL, NULL, 0 }
1955
};
1956
1957
static void usage(void)
1958
{
1959
int i;
1960
1961
printf("hciconfig - HCI device configuration utility\n");
1962
printf("Usage:\n"
1963
"\thciconfig\n"
1964
"\thciconfig [-a] hciX [command ...]\n");
1965
printf("Commands:\n");
1966
for (i = 0; command[i].cmd; i++)
1967
printf("\t%-10s %-8s\t%s\n", command[i].cmd,
1968
command[i].opt ? command[i].opt : " ",
1969
command[i].doc);
1970
}
1971
1972
static struct option main_options[] = {
1973
{ "help", 0, 0, 'h' },
1974
{ "all", 0, 0, 'a' },
1975
{ 0, 0, 0, 0 }
1976
};
1977
1978
int main(int argc, char *argv[])
1979
{
1980
int opt, ctl, i, cmd = 0;
1981
1982
while ((opt = getopt_long(argc, argv, "ah", main_options, NULL)) != -1) {
1983
switch (opt) {
1984
case 'a':
1985
all = 1;
1986
break;
1987
1988
case 'h':
1989
default:
1990
usage();
1991
exit(0);
1992
}
1993
}
1994
1995
argc -= optind;
1996
argv += optind;
1997
optind = 0;
1998
1999
/* Open HCI socket */
2000
if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) {
2001
perror("Can't open HCI socket.");
2002
exit(1);
2003
}
2004
2005
if (argc < 1) {
2006
print_dev_list(ctl, 0);
2007
exit(0);
2008
}
2009
2010
di.dev_id = atoi(argv[0] + 3);
2011
argc--; argv++;
2012
2013
if (ioctl(ctl, HCIGETDEVINFO, (void *) &di)) {
2014
perror("Can't get device info");
2015
exit(1);
2016
}
2017
2018
if (hci_test_bit(HCI_RAW, &di.flags) &&
2019
!bacmp(&di.bdaddr, BDADDR_ANY)) {
2020
int dd = hci_open_dev(di.dev_id);
2021
hci_read_bd_addr(dd, &di.bdaddr, 1000);
2022
hci_close_dev(dd);
2023
}
2024
2025
while (argc > 0) {
2026
for (i = 0; command[i].cmd; i++) {
2027
if (strncmp(command[i].cmd,
2028
*argv, strlen(command[i].cmd)))
2029
continue;
2030
2031
if (command[i].opt) {
2032
argc--; argv++;
2033
}
2034
2035
command[i].func(ctl, di.dev_id, *argv);
2036
cmd = 1;
2037
break;
2038
}
2039
2040
if (command[i].cmd == 0)
2041
fprintf(stderr, "Warning: unknown command - \"%s\"\n",
2042
*argv);
2043
2044
argc--; argv++;
2045
}
2046
2047
if (!cmd)
2048
print_dev_info(ctl, &di);
2049
2050
close(ctl);
2051
return 0;
2052
}
2053
2054