OSDN Git Service

eclair snapshot
[android-x86/external-bluetooth-bluez.git] / tools / hciconfig.c
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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  */
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }