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