~ubuntu-branches/ubuntu/intrepid/bluez/intrepid

« back to all changes in this revision

Viewing changes to tools/hcitool.c

  • Committer: Bazaar Package Importer
  • Author(s): Mario Limonciello
  • Date: 2008-10-07 12:10:29 UTC
  • Revision ID: james.westby@ubuntu.com-20081007121029-4gup4fmmh2vfo5nh
Tags: upstream-4.12
ImportĀ upstreamĀ versionĀ 4.12

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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-2008  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 <fcntl.h>
 
34
#include <unistd.h>
 
35
#include <stdlib.h>
 
36
#include <string.h>
 
37
#include <getopt.h>
 
38
#include <sys/param.h>
 
39
#include <sys/ioctl.h>
 
40
#include <sys/socket.h>
 
41
 
 
42
#include <bluetooth/bluetooth.h>
 
43
#include <bluetooth/hci.h>
 
44
#include <bluetooth/hci_lib.h>
 
45
 
 
46
#include "textfile.h"
 
47
#include "oui.h"
 
48
 
 
49
#define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, NULL)) != -1)
 
50
 
 
51
static void usage(void);
 
52
 
 
53
static int dev_info(int s, int dev_id, long arg)
 
54
{
 
55
        struct hci_dev_info di = { dev_id: dev_id };
 
56
        char addr[18];
 
57
 
 
58
        if (ioctl(s, HCIGETDEVINFO, (void *) &di))
 
59
                return 0;
 
60
 
 
61
        ba2str(&di.bdaddr, addr);
 
62
        printf("\t%s\t%s\n", di.name, addr);
 
63
        return 0;
 
64
}
 
65
 
 
66
static char *type2str(uint8_t type)
 
67
{
 
68
        switch (type) {
 
69
        case SCO_LINK:
 
70
                return "SCO";
 
71
        case ACL_LINK:
 
72
                return "ACL";
 
73
        case ESCO_LINK:
 
74
                return "eSCO";
 
75
        default:
 
76
                return "Unknown";
 
77
        }
 
78
}
 
79
 
 
80
static int conn_list(int s, int dev_id, long arg)
 
81
{
 
82
        struct hci_conn_list_req *cl;
 
83
        struct hci_conn_info *ci;
 
84
        int id = arg;
 
85
        int i;
 
86
 
 
87
        if (id != -1 && dev_id != id)
 
88
                return 0;
 
89
 
 
90
        if (!(cl = malloc(10 * sizeof(*ci) + sizeof(*cl)))) {
 
91
                perror("Can't allocate memory");
 
92
                exit(1);
 
93
        }
 
94
        cl->dev_id = dev_id;
 
95
        cl->conn_num = 10;
 
96
        ci = cl->conn_info;
 
97
 
 
98
        if (ioctl(s, HCIGETCONNLIST, (void *) cl)) {
 
99
                perror("Can't get connection list");
 
100
                exit(1);
 
101
        }
 
102
 
 
103
        for (i = 0; i < cl->conn_num; i++, ci++) {
 
104
                char addr[18];
 
105
                ba2str(&ci->bdaddr, addr);
 
106
                printf("\t%s %s %s handle %d state %d lm %s\n",
 
107
                        ci->out ? "<" : ">", type2str(ci->type),
 
108
                        addr, ci->handle, ci->state,
 
109
                        hci_lmtostr(ci->link_mode));
 
110
        }
 
111
 
 
112
        return 0;
 
113
}
 
114
 
 
115
static int find_conn(int s, int dev_id, long arg)
 
116
{
 
117
        struct hci_conn_list_req *cl;
 
118
        struct hci_conn_info *ci;
 
119
        int i;
 
120
 
 
121
        if (!(cl = malloc(10 * sizeof(*ci) + sizeof(*cl)))) {
 
122
                perror("Can't allocate memory");
 
123
                exit(1);
 
124
        }
 
125
        cl->dev_id = dev_id;
 
126
        cl->conn_num = 10;
 
127
        ci = cl->conn_info;
 
128
 
 
129
        if (ioctl(s, HCIGETCONNLIST, (void *) cl)) {
 
130
                perror("Can't get connection list");
 
131
                exit(1);
 
132
        }
 
133
 
 
134
        for (i = 0; i < cl->conn_num; i++, ci++)
 
135
                if (!bacmp((bdaddr_t *) arg, &ci->bdaddr))
 
136
                        return 1;
 
137
 
 
138
        return 0;
 
139
}
 
140
 
 
141
static void hex_dump(char *pref, int width, unsigned char *buf, int len)
 
142
{
 
143
        register int i,n;
 
144
 
 
145
        for (i = 0, n = 1; i < len; i++, n++) {
 
146
                if (n == 1)
 
147
                        printf("%s", pref);
 
148
                printf("%2.2X ", buf[i]);
 
149
                if (n == width) {
 
150
                        printf("\n");
 
151
                        n = 0;
 
152
                }
 
153
        }
 
154
        if (i && n!=1)
 
155
                printf("\n");
 
156
}
 
157
 
 
158
static char *get_minor_device_name(int major, int minor)
 
159
{
 
160
        switch (major) {
 
161
        case 0: /* misc */
 
162
                return "";
 
163
        case 1: /* computer */
 
164
                switch(minor) {
 
165
                case 0:
 
166
                        return "Uncategorized";
 
167
                case 1:
 
168
                        return "Desktop workstation";
 
169
                case 2:
 
170
                        return "Server";
 
171
                case 3:
 
172
                        return "Laptop";
 
173
                case 4:
 
174
                        return "Handheld";
 
175
                case 5:
 
176
                        return "Palm";
 
177
                case 6:
 
178
                        return "Wearable";
 
179
                }
 
180
                break;
 
181
        case 2: /* phone */
 
182
                switch(minor) {
 
183
                case 0:
 
184
                        return "Uncategorized";
 
185
                case 1:
 
186
                        return "Cellular";
 
187
                case 2:
 
188
                        return "Cordless";
 
189
                case 3:
 
190
                        return "Smart phone";
 
191
                case 4:
 
192
                        return "Wired modem or voice gateway";
 
193
                case 5:
 
194
                        return "Common ISDN Access";
 
195
                case 6:
 
196
                        return "Sim Card Reader";
 
197
                }
 
198
                break;
 
199
        case 3: /* lan access */
 
200
                if (minor == 0)
 
201
                        return "Uncategorized";
 
202
                switch(minor / 8) {
 
203
                case 0:
 
204
                        return "Fully available";
 
205
                case 1:
 
206
                        return "1-17% utilized";
 
207
                case 2:
 
208
                        return "17-33% utilized";
 
209
                case 3:
 
210
                        return "33-50% utilized";
 
211
                case 4:
 
212
                        return "50-67% utilized";
 
213
                case 5:
 
214
                        return "67-83% utilized";
 
215
                case 6:
 
216
                        return "83-99% utilized";
 
217
                case 7:
 
218
                        return "No service available";
 
219
                }
 
220
                break;
 
221
        case 4: /* audio/video */
 
222
                switch(minor) {
 
223
                case 0:
 
224
                        return "Uncategorized";
 
225
                case 1:
 
226
                        return "Device conforms to the Headset profile";
 
227
                case 2:
 
228
                        return "Hands-free";
 
229
                        /* 3 is reserved */
 
230
                case 4:
 
231
                        return "Microphone";
 
232
                case 5:
 
233
                        return "Loudspeaker";
 
234
                case 6:
 
235
                        return "Headphones";
 
236
                case 7:
 
237
                        return "Portable Audio";
 
238
                case 8:
 
239
                        return "Car Audio";
 
240
                case 9:
 
241
                        return "Set-top box";
 
242
                case 10:
 
243
                        return "HiFi Audio Device";
 
244
                case 11:
 
245
                        return "VCR";
 
246
                case 12:
 
247
                        return "Video Camera";
 
248
                case 13:
 
249
                        return "Camcorder";
 
250
                case 14:
 
251
                        return "Video Monitor";
 
252
                case 15:
 
253
                        return "Video Display and Loudspeaker";
 
254
                case 16:
 
255
                        return "Video Conferencing";
 
256
                        /* 17 is reserved */
 
257
                case 18:
 
258
                        return "Gaming/Toy";
 
259
                }
 
260
                break;
 
261
        case 5: /* peripheral */ {
 
262
                static char cls_str[48]; cls_str[0] = 0;
 
263
 
 
264
                switch(minor & 48) {
 
265
                case 16:
 
266
                        strncpy(cls_str, "Keyboard", sizeof(cls_str));
 
267
                        break;
 
268
                case 32:
 
269
                        strncpy(cls_str, "Pointing device", sizeof(cls_str));
 
270
                        break;
 
271
                case 48:
 
272
                        strncpy(cls_str, "Combo keyboard/pointing device", sizeof(cls_str));
 
273
                        break;
 
274
                }
 
275
                if((minor & 15) && (strlen(cls_str) > 0))
 
276
                        strcat(cls_str, "/");
 
277
 
 
278
                switch(minor & 15) {
 
279
                case 0:
 
280
                        break;
 
281
                case 1:
 
282
                        strncat(cls_str, "Joystick", sizeof(cls_str) - strlen(cls_str));
 
283
                        break;
 
284
                case 2:
 
285
                        strncat(cls_str, "Gamepad", sizeof(cls_str) - strlen(cls_str));
 
286
                        break;
 
287
                case 3:
 
288
                        strncat(cls_str, "Remote control", sizeof(cls_str) - strlen(cls_str));
 
289
                        break;
 
290
                case 4:
 
291
                        strncat(cls_str, "Sensing device", sizeof(cls_str) - strlen(cls_str));
 
292
                        break;
 
293
                case 5:
 
294
                        strncat(cls_str, "Digitizer tablet", sizeof(cls_str) - strlen(cls_str));
 
295
                break;
 
296
                case 6:
 
297
                        strncat(cls_str, "Card reader", sizeof(cls_str) - strlen(cls_str));
 
298
                        break;
 
299
                default:
 
300
                        strncat(cls_str, "(reserved)", sizeof(cls_str) - strlen(cls_str));
 
301
                        break;
 
302
                }
 
303
                if(strlen(cls_str) > 0)
 
304
                        return cls_str;
 
305
        }
 
306
        case 6: /* imaging */
 
307
                if (minor & 4)
 
308
                        return "Display";
 
309
                if (minor & 8)
 
310
                        return "Camera";
 
311
                if (minor & 16)
 
312
                        return "Scanner";
 
313
                if (minor & 32)
 
314
                        return "Printer";
 
315
                break;
 
316
        case 7: /* wearable */
 
317
                switch(minor) {
 
318
                case 1:
 
319
                        return "Wrist Watch";
 
320
                case 2:
 
321
                        return "Pager";
 
322
                case 3:
 
323
                        return "Jacket";
 
324
                case 4:
 
325
                        return "Helmet";
 
326
                case 5:
 
327
                        return "Glasses";
 
328
                }
 
329
                break;
 
330
        case 8: /* toy */
 
331
                switch(minor) {
 
332
                case 1:
 
333
                        return "Robot";
 
334
                case 2:
 
335
                        return "Vehicle";
 
336
                case 3:
 
337
                        return "Doll / Action Figure";
 
338
                case 4:
 
339
                        return "Controller";
 
340
                case 5:
 
341
                        return "Game";
 
342
                }
 
343
                break;
 
344
        case 63:        /* uncategorised */
 
345
                return "";
 
346
        }
 
347
        return "Unknown (reserved) minor device class";
 
348
}
 
349
 
 
350
static char *major_classes[] = {
 
351
        "Miscellaneous", "Computer", "Phone", "LAN Access",
 
352
        "Audio/Video", "Peripheral", "Imaging", "Uncategorized"
 
353
};
 
354
 
 
355
static char *get_device_name(const bdaddr_t *local, const bdaddr_t *peer)
 
356
{
 
357
        char filename[PATH_MAX + 1], addr[18];
 
358
 
 
359
        ba2str(local, addr);
 
360
        create_name(filename, PATH_MAX, STORAGEDIR, addr, "names");
 
361
 
 
362
        ba2str(peer, addr);
 
363
        return textfile_get(filename, addr);
 
364
}
 
365
 
 
366
/* Display local devices */
 
367
 
 
368
static struct option dev_options[] = {
 
369
        { "help",       0, 0, 'h' },
 
370
        {0, 0, 0, 0 }
 
371
};
 
372
 
 
373
static const char *dev_help =
 
374
        "Usage:\n"
 
375
        "\tdev\n";
 
376
 
 
377
static void cmd_dev(int dev_id, int argc, char **argv)
 
378
{
 
379
        int opt;
 
380
 
 
381
        for_each_opt(opt, dev_options, NULL) {
 
382
                switch (opt) {
 
383
                default:
 
384
                        printf(dev_help);
 
385
                        return;
 
386
                }
 
387
        }
 
388
 
 
389
        printf("Devices:\n");
 
390
 
 
391
        hci_for_each_dev(HCI_UP, dev_info, 0);
 
392
}
 
393
 
 
394
/* Inquiry */
 
395
 
 
396
static struct option inq_options[] = {
 
397
        { "help",       0, 0, 'h' },
 
398
        { "length",     1, 0, 'l' },
 
399
        { "numrsp",     1, 0, 'n' },
 
400
        { "iac",        1, 0, 'i' },
 
401
        { "flush",      0, 0, 'f' },
 
402
        { 0, 0, 0, 0 }
 
403
};
 
404
 
 
405
static const char *inq_help =
 
406
        "Usage:\n"
 
407
        "\tinq [--length=N] maximum inquiry duration in 1.28 s units\n"
 
408
        "\t    [--numrsp=N] specify maximum number of inquiry responses\n"
 
409
        "\t    [--iac=lap]  specify the inquiry access code\n"
 
410
        "\t    [--flush]    flush the inquiry cache\n";
 
411
 
 
412
static void cmd_inq(int dev_id, int argc, char **argv)
 
413
{
 
414
        inquiry_info *info = NULL;
 
415
        uint8_t lap[3] = { 0x33, 0x8b, 0x9e };
 
416
        int num_rsp, length, flags;
 
417
        char addr[18];
 
418
        int i, l, opt;
 
419
 
 
420
        length  = 8;    /* ~10 seconds */
 
421
        num_rsp = 0;
 
422
        flags   = 0;
 
423
 
 
424
        for_each_opt(opt, inq_options, NULL) {
 
425
                switch (opt) {
 
426
                case 'l':
 
427
                        length = atoi(optarg);
 
428
                        break;
 
429
 
 
430
                case 'n':
 
431
                        num_rsp = atoi(optarg);
 
432
                        break;
 
433
 
 
434
                case 'i':
 
435
                        l = strtoul(optarg, 0, 16);
 
436
                        if (!strcasecmp(optarg, "giac")) {
 
437
                                l = 0x9e8b33;
 
438
                        } else if (!strcasecmp(optarg, "liac")) {
 
439
                                l = 0x9e8b00;
 
440
                        } if (l < 0x9e8b00 || l > 0x9e8b3f) {
 
441
                                printf("Invalid access code 0x%x\n", l);
 
442
                                exit(1);
 
443
                        }
 
444
                        lap[0] = (l & 0xff);
 
445
                        lap[1] = (l >> 8) & 0xff;
 
446
                        lap[2] = (l >> 16) & 0xff;
 
447
                        break;
 
448
 
 
449
                case 'f':
 
450
                        flags |= IREQ_CACHE_FLUSH;
 
451
                        break;
 
452
 
 
453
                default:
 
454
                        printf(inq_help);
 
455
                        return;
 
456
                }
 
457
        }
 
458
 
 
459
        printf("Inquiring ...\n");
 
460
 
 
461
        num_rsp = hci_inquiry(dev_id, length, num_rsp, lap, &info, flags);
 
462
        if (num_rsp < 0) {
 
463
                perror("Inquiry failed.");
 
464
                exit(1);
 
465
        }
 
466
 
 
467
        for (i = 0; i < num_rsp; i++) {
 
468
                ba2str(&(info+i)->bdaddr, addr);
 
469
                printf("\t%s\tclock offset: 0x%4.4x\tclass: 0x%2.2x%2.2x%2.2x\n",
 
470
                        addr, btohs((info+i)->clock_offset),
 
471
                        (info+i)->dev_class[2],
 
472
                        (info+i)->dev_class[1],
 
473
                        (info+i)->dev_class[0]);
 
474
        }
 
475
 
 
476
        bt_free(info);
 
477
}
 
478
 
 
479
/* Device scanning */
 
480
 
 
481
static struct option scan_options[] = {
 
482
        { "help",       0, 0, 'h' },
 
483
        { "length",     1, 0, 'l' },
 
484
        { "numrsp",     1, 0, 'n' },
 
485
        { "iac",        1, 0, 'i' },
 
486
        { "flush",      0, 0, 'f' },
 
487
        { "refresh",    0, 0, 'r' },
 
488
        { "class",      0, 0, 'C' },
 
489
        { "info",       0, 0, 'I' },
 
490
        { "oui",        0, 0, 'O' },
 
491
        { "all",        0, 0, 'A' },
 
492
        { "ext",        0, 0, 'A' },
 
493
        { 0, 0, 0, 0 }
 
494
};
 
495
 
 
496
static const char *scan_help =
 
497
        "Usage:\n"
 
498
        "\tscan [--length=N] [--numrsp=N] [--iac=lap] [--flush] [--class] [--info] [--oui] [--refresh]\n";
 
499
 
 
500
static void cmd_scan(int dev_id, int argc, char **argv)
 
501
{
 
502
        inquiry_info *info = NULL;
 
503
        uint8_t lap[3] = { 0x33, 0x8b, 0x9e };
 
504
        int num_rsp, length, flags;
 
505
        uint8_t cls[3], features[8];
 
506
        uint16_t handle;
 
507
        char addr[18], name[249], oui[9], *comp, *tmp;
 
508
        struct hci_version version;
 
509
        struct hci_dev_info di;
 
510
        struct hci_conn_info_req *cr;
 
511
        int refresh = 0, extcls = 0, extinf = 0, extoui = 0;
 
512
        int i, n, l, opt, dd, cc, nc;
 
513
 
 
514
        length  = 8;    /* ~10 seconds */
 
515
        num_rsp = 0;
 
516
        flags   = 0;
 
517
 
 
518
        for_each_opt(opt, scan_options, NULL) {
 
519
                switch (opt) {
 
520
                case 'l':
 
521
                        length = atoi(optarg);
 
522
                        break;
 
523
 
 
524
                case 'n':
 
525
                        num_rsp = atoi(optarg);
 
526
                        break;
 
527
 
 
528
                case 'i':
 
529
                        l = strtoul(optarg, 0, 16);
 
530
                        if (!strcasecmp(optarg, "giac")) {
 
531
                                l = 0x9e8b33;
 
532
                        } else if (!strcasecmp(optarg, "liac")) {
 
533
                                l = 0x9e8b00;
 
534
                        } else if (l < 0x9e8b00 || l > 0x9e8b3f) {
 
535
                                printf("Invalid access code 0x%x\n", l);
 
536
                                exit(1);
 
537
                        }
 
538
                        lap[0] = (l & 0xff);
 
539
                        lap[1] = (l >> 8) & 0xff;
 
540
                        lap[2] = (l >> 16) & 0xff;
 
541
                        break;
 
542
 
 
543
                case 'f':
 
544
                        flags |= IREQ_CACHE_FLUSH;
 
545
                        break;
 
546
 
 
547
                case 'r':
 
548
                        refresh = 1;
 
549
                        break;
 
550
 
 
551
                case 'C':
 
552
                        extcls = 1;
 
553
                        break;
 
554
 
 
555
                case 'I':
 
556
                        extinf = 1;
 
557
                        break;
 
558
 
 
559
                case 'O':
 
560
                        extoui = 1;
 
561
                        break;
 
562
 
 
563
                case 'A':
 
564
                        extcls = 1;
 
565
                        extinf = 1;
 
566
                        extoui = 1;
 
567
                        break;
 
568
 
 
569
                default:
 
570
                        printf(scan_help);
 
571
                        return;
 
572
                }
 
573
        }
 
574
 
 
575
        if (dev_id < 0) {
 
576
                dev_id = hci_get_route(NULL);
 
577
                if (dev_id < 0) {
 
578
                        perror("Device is not available");
 
579
                        exit(1);
 
580
                }
 
581
        }
 
582
 
 
583
        if (hci_devinfo(dev_id, &di) < 0) {
 
584
                perror("Can't get device info");
 
585
                exit(1);
 
586
        }
 
587
 
 
588
        printf("Scanning ...\n");
 
589
        num_rsp = hci_inquiry(dev_id, length, num_rsp, lap, &info, flags);
 
590
        if (num_rsp < 0) {
 
591
                perror("Inquiry failed");
 
592
                exit(1);
 
593
        }
 
594
 
 
595
        dd = hci_open_dev(dev_id);
 
596
        if (dd < 0) {
 
597
                perror("HCI device open failed");
 
598
                free(info);
 
599
                exit(1);
 
600
        }
 
601
 
 
602
        if (extcls || extinf || extoui)
 
603
                printf("\n");
 
604
 
 
605
        for (i = 0; i < num_rsp; i++) {
 
606
                if (!refresh) {
 
607
                        memset(name, 0, sizeof(name));
 
608
                        tmp = get_device_name(&di.bdaddr, &(info+i)->bdaddr);
 
609
                        if (tmp) {
 
610
                                strncpy(name, tmp, 249);
 
611
                                free(tmp);
 
612
                                nc = 1;
 
613
                        } else
 
614
                                nc = 0;
 
615
                } else
 
616
                        nc = 0;
 
617
 
 
618
                if (!extcls && !extinf && !extoui) {
 
619
                        ba2str(&(info+i)->bdaddr, addr);
 
620
 
 
621
                        if (nc) {
 
622
                                printf("\t%s\t%s\n", addr, name);
 
623
                                continue;
 
624
                        }
 
625
 
 
626
                        if (hci_read_remote_name_with_clock_offset(dd,
 
627
                                        &(info+i)->bdaddr,
 
628
                                        (info+i)->pscan_rep_mode,
 
629
                                        (info+i)->clock_offset | 0x8000,
 
630
                                        sizeof(name), name, 100000) < 0)
 
631
                                strcpy(name, "n/a");
 
632
 
 
633
                        for (n = 0; n < 248 && name[n]; n++) {
 
634
                                if ((unsigned char) name[i] < 32 || name[i] == 127)
 
635
                                        name[i] = '.';
 
636
                        }
 
637
 
 
638
                        name[248] = '\0';
 
639
 
 
640
                        printf("\t%s\t%s\n", addr, name);
 
641
                        continue;
 
642
                }
 
643
 
 
644
                ba2str(&(info+i)->bdaddr, addr);
 
645
                printf("BD Address:\t%s [mode %d, clkoffset 0x%4.4x]\n", addr,
 
646
                        (info+i)->pscan_rep_mode, btohs((info+i)->clock_offset));
 
647
 
 
648
                if (extoui) {
 
649
                        ba2oui(&(info+i)->bdaddr, oui);
 
650
                        comp = ouitocomp(oui);
 
651
                        if (comp) {
 
652
                                printf("OUI company:\t%s (%s)\n", comp, oui);
 
653
                                free(comp);
 
654
                        }
 
655
                }
 
656
 
 
657
                cc = 0;
 
658
 
 
659
                if (extinf) {
 
660
                        cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
 
661
                        if (cr) {
 
662
                                bacpy(&cr->bdaddr, &(info+i)->bdaddr);
 
663
                                cr->type = ACL_LINK;
 
664
                                if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
 
665
                                        handle = 0;
 
666
                                        cc = 1;
 
667
                                } else {
 
668
                                        handle = htobs(cr->conn_info->handle);
 
669
                                        cc = 0;
 
670
                                }
 
671
                                free(cr);
 
672
                        }
 
673
 
 
674
                        if (cc) {
 
675
                                if (hci_create_connection(dd, &(info+i)->bdaddr,
 
676
                                                htobs(di.pkt_type & ACL_PTYPE_MASK),
 
677
                                                (info+i)->clock_offset | 0x8000,
 
678
                                                0x01, &handle, 25000) < 0) {
 
679
                                        handle = 0;
 
680
                                        cc = 0;
 
681
                                }
 
682
                        }
 
683
                }
 
684
 
 
685
                if (handle > 0 || !nc) {
 
686
                        if (hci_read_remote_name_with_clock_offset(dd,
 
687
                                        &(info+i)->bdaddr,
 
688
                                        (info+i)->pscan_rep_mode,
 
689
                                        (info+i)->clock_offset | 0x8000,
 
690
                                        sizeof(name), name, 100000) < 0) {
 
691
                                if (!nc)
 
692
                                        strcpy(name, "n/a");
 
693
                        } else {
 
694
                                for (n = 0; n < 248 && name[n]; n++) {
 
695
                                        if ((unsigned char) name[i] < 32 || name[i] == 127)
 
696
                                                name[i] = '.';
 
697
                                }
 
698
 
 
699
                                name[248] = '\0';
 
700
                                nc = 0;
 
701
                        }
 
702
                }
 
703
 
 
704
                if (strlen(name) > 0)
 
705
                        printf("Device name:\t%s%s\n", name, nc ? " [cached]" : "");
 
706
 
 
707
                if (extcls) {
 
708
                        memcpy(cls, (info+i)->dev_class, 3);
 
709
                        printf("Device class:\t");
 
710
                        if ((cls[1] & 0x1f) > sizeof(major_classes) / sizeof(char *))
 
711
                                printf("Invalid");
 
712
                        else
 
713
                                printf("%s, %s", major_classes[cls[1] & 0x1f],
 
714
                                        get_minor_device_name(cls[1] & 0x1f, cls[0] >> 2));
 
715
                        printf(" (0x%2.2x%2.2x%2.2x)\n", cls[2], cls[1], cls[0]);
 
716
                }
 
717
 
 
718
                if (extinf && handle > 0) {
 
719
                        if (hci_read_remote_version(dd, handle, &version, 20000) == 0) {
 
720
                                char *ver = lmp_vertostr(version.lmp_ver);
 
721
                                printf("Manufacturer:\t%s (%d)\n",
 
722
                                        bt_compidtostr(version.manufacturer),
 
723
                                        version.manufacturer);
 
724
                                printf("LMP version:\t%s (0x%x) [subver 0x%x]\n",
 
725
                                        ver ? ver : "n/a",
 
726
                                        version.lmp_ver, version.lmp_subver);
 
727
                                if (ver)
 
728
                                        bt_free(ver);
 
729
                        }
 
730
 
 
731
                        if (hci_read_remote_features(dd, handle, features, 20000) == 0) {
 
732
                                char *tmp = lmp_featurestostr(features, "\t\t", 63);
 
733
                                printf("LMP features:\t0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x"
 
734
                                        " 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n",
 
735
                                        features[0], features[1],
 
736
                                        features[2], features[3],
 
737
                                        features[4], features[5],
 
738
                                        features[6], features[7]);
 
739
                                printf("%s\n", tmp);
 
740
                                bt_free(tmp);
 
741
                        }
 
742
 
 
743
                        if (cc) {
 
744
                                usleep(10000);
 
745
                                hci_disconnect(dd, handle, HCI_OE_USER_ENDED_CONNECTION, 10000);
 
746
                        }
 
747
                }
 
748
 
 
749
                printf("\n");
 
750
        }
 
751
 
 
752
        bt_free(info);
 
753
 
 
754
        hci_close_dev(dd);
 
755
}
 
756
 
 
757
/* Remote name */
 
758
 
 
759
static struct option name_options[] = {
 
760
        { "help",       0, 0, 'h' },
 
761
        { 0, 0, 0, 0 }
 
762
};
 
763
 
 
764
static const char *name_help =
 
765
        "Usage:\n"
 
766
        "\tname <bdaddr>\n";
 
767
 
 
768
static void cmd_name(int dev_id, int argc, char **argv)
 
769
{
 
770
        bdaddr_t bdaddr;
 
771
        char name[248];
 
772
        int opt, dd;
 
773
 
 
774
        for_each_opt(opt, name_options, NULL) {
 
775
                switch (opt) {
 
776
                default:
 
777
                        printf(name_help);
 
778
                        return;
 
779
                }
 
780
        }
 
781
        argc -= optind;
 
782
        argv += optind;
 
783
 
 
784
        if (argc < 1) {
 
785
                printf(name_help);
 
786
                return;
 
787
        }
 
788
 
 
789
        str2ba(argv[0], &bdaddr);
 
790
 
 
791
        if (dev_id < 0) {
 
792
                dev_id = hci_get_route(&bdaddr);
 
793
                if (dev_id < 0) {
 
794
                        fprintf(stderr, "Device is not available.\n");
 
795
                        exit(1);
 
796
                }
 
797
        }
 
798
 
 
799
        dd = hci_open_dev(dev_id);
 
800
        if (dd < 0) {
 
801
                perror("HCI device open failed");
 
802
                exit(1);
 
803
        }
 
804
 
 
805
        if (hci_read_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0)
 
806
                printf("%s\n", name);
 
807
 
 
808
        hci_close_dev(dd);
 
809
}
 
810
 
 
811
/* Info about remote device */
 
812
 
 
813
static struct option info_options[] = {
 
814
        { "help",       0, 0, 'h' },
 
815
        { 0, 0, 0, 0 }
 
816
};
 
817
 
 
818
static const char *info_help =
 
819
        "Usage:\n"
 
820
        "\tinfo <bdaddr>\n";
 
821
 
 
822
static void cmd_info(int dev_id, int argc, char **argv)
 
823
{
 
824
        bdaddr_t bdaddr;
 
825
        uint16_t handle;
 
826
        uint8_t features[8], max_page = 0;
 
827
        char name[249], oui[9], *comp, *tmp;
 
828
        struct hci_version version;
 
829
        struct hci_dev_info di;
 
830
        struct hci_conn_info_req *cr;
 
831
        int i, opt, dd, cc = 0;
 
832
 
 
833
        for_each_opt(opt, info_options, NULL) {
 
834
                switch (opt) {
 
835
                default:
 
836
                        printf(info_help);
 
837
                        return;
 
838
                }
 
839
        }
 
840
        argc -= optind;
 
841
        argv += optind;
 
842
 
 
843
        if (argc < 1) {
 
844
                printf(info_help);
 
845
                return;
 
846
        }
 
847
 
 
848
        str2ba(argv[0], &bdaddr);
 
849
 
 
850
        if (dev_id < 0)
 
851
                dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
 
852
 
 
853
        if (dev_id < 0)
 
854
                dev_id = hci_get_route(&bdaddr);
 
855
 
 
856
        if (dev_id < 0) {
 
857
                fprintf(stderr, "Device is not available or not connected.\n");
 
858
                exit(1);
 
859
        }
 
860
 
 
861
        if (hci_devinfo(dev_id, &di) < 0) {
 
862
                perror("Can't get device info");
 
863
                exit(1);
 
864
        }
 
865
 
 
866
        printf("Requesting information ...\n");
 
867
 
 
868
        dd = hci_open_dev(dev_id);
 
869
        if (dd < 0) {
 
870
                perror("HCI device open failed");
 
871
                exit(1);
 
872
        }
 
873
 
 
874
        cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
 
875
        if (!cr) {
 
876
                perror("Can't get connection info");
 
877
                close(dd);
 
878
                exit(1);
 
879
        }
 
880
 
 
881
        bacpy(&cr->bdaddr, &bdaddr);
 
882
        cr->type = ACL_LINK;
 
883
        if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
 
884
                if (hci_create_connection(dd, &bdaddr,
 
885
                                        htobs(di.pkt_type & ACL_PTYPE_MASK),
 
886
                                        0, 0x01, &handle, 25000) < 0) {
 
887
                        perror("Can't create connection");
 
888
                        close(dd);
 
889
                        exit(1);
 
890
                }
 
891
                cc = 1;
 
892
        } else
 
893
                handle = htobs(cr->conn_info->handle);
 
894
 
 
895
        printf("\tBD Address:  %s\n", argv[0]);
 
896
 
 
897
        ba2oui(&bdaddr, oui);
 
898
        comp = ouitocomp(oui);
 
899
        if (comp) {
 
900
                printf("\tOUI Company: %s (%s)\n", comp, oui);
 
901
                free(comp);
 
902
        }
 
903
 
 
904
        if (hci_read_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0)
 
905
                printf("\tDevice Name: %s\n", name);
 
906
 
 
907
        if (hci_read_remote_version(dd, handle, &version, 20000) == 0) {
 
908
                char *ver = lmp_vertostr(version.lmp_ver);
 
909
                printf("\tLMP Version: %s (0x%x) LMP Subversion: 0x%x\n"
 
910
                        "\tManufacturer: %s (%d)\n",
 
911
                        ver ? ver : "n/a",
 
912
                        version.lmp_ver,
 
913
                        version.lmp_subver,
 
914
                        bt_compidtostr(version.manufacturer),
 
915
                        version.manufacturer);
 
916
                if (ver)
 
917
                        bt_free(ver);
 
918
        }
 
919
 
 
920
        memset(features, 0, sizeof(features));
 
921
        hci_read_remote_features(dd, handle, features, 20000);
 
922
 
 
923
        if ((di.features[7] & LMP_EXT_FEAT) && (features[7] & LMP_EXT_FEAT))
 
924
                hci_read_remote_ext_features(dd, handle, 0, &max_page,
 
925
                                                        features, 20000);
 
926
 
 
927
        printf("\tFeatures%s: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
 
928
                                "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n",
 
929
                (max_page > 0) ? " page 0" : "",
 
930
                features[0], features[1], features[2], features[3],
 
931
                features[4], features[5], features[6], features[7]);
 
932
 
 
933
        tmp = lmp_featurestostr(features, "\t\t", 63);
 
934
        printf("%s\n", tmp);
 
935
        bt_free(tmp);
 
936
 
 
937
        for (i = 1; i <= max_page; i++) {
 
938
                if (hci_read_remote_ext_features(dd, handle, i, NULL,
 
939
                                                        features, 20000) < 0)
 
940
                        continue;
 
941
 
 
942
                printf("\tFeatures page %d: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
 
943
                                        "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", i,
 
944
                        features[0], features[1], features[2], features[3],
 
945
                        features[4], features[5], features[6], features[7]);
 
946
        }
 
947
 
 
948
        if (cc) {
 
949
                usleep(10000);
 
950
                hci_disconnect(dd, handle, HCI_OE_USER_ENDED_CONNECTION, 10000);
 
951
        }
 
952
 
 
953
        hci_close_dev(dd);
 
954
}
 
955
 
 
956
/* Start periodic inquiry */
 
957
 
 
958
static struct option spinq_options[] = {
 
959
        { "help",       0, 0, 'h' },
 
960
        { 0, 0, 0, 0 }
 
961
};
 
962
 
 
963
static const char *spinq_help =
 
964
        "Usage:\n"
 
965
        "\tspinq\n";
 
966
 
 
967
static void cmd_spinq(int dev_id, int argc, char **argv)
 
968
{
 
969
        uint8_t lap[3] = { 0x33, 0x8b, 0x9e };
 
970
        struct hci_request rq;
 
971
        periodic_inquiry_cp cp;
 
972
        int opt, dd;
 
973
 
 
974
        for_each_opt(opt, spinq_options, NULL) {
 
975
                switch (opt) {
 
976
                default:
 
977
                        printf(spinq_help);
 
978
                        return;
 
979
                }
 
980
        }
 
981
 
 
982
        if (dev_id < 0)
 
983
                dev_id = hci_get_route(NULL);
 
984
 
 
985
        dd = hci_open_dev(dev_id);
 
986
        if (dd < 0) {
 
987
                perror("Device open failed");
 
988
                exit(EXIT_FAILURE);
 
989
        }
 
990
 
 
991
        memset(&cp, 0, sizeof(cp));
 
992
        memcpy(cp.lap, lap, 3);
 
993
        cp.max_period = htobs(16);
 
994
        cp.min_period = htobs(10);
 
995
        cp.length     = 8;
 
996
        cp.num_rsp    = 0;
 
997
 
 
998
        memset(&rq, 0, sizeof(rq));
 
999
        rq.ogf    = OGF_LINK_CTL;
 
1000
        rq.ocf    = OCF_PERIODIC_INQUIRY;
 
1001
        rq.cparam = &cp;
 
1002
        rq.clen   = PERIODIC_INQUIRY_CP_SIZE;
 
1003
 
 
1004
        if (hci_send_req(dd, &rq, 100) < 0) {
 
1005
                perror("Periodic inquiry failed");
 
1006
                exit(EXIT_FAILURE);
 
1007
        }
 
1008
 
 
1009
        hci_close_dev(dd);
 
1010
}
 
1011
 
 
1012
/* Exit periodic inquiry */
 
1013
 
 
1014
static struct option epinq_options[] = {
 
1015
        { "help",       0, 0, 'h' },
 
1016
        { 0, 0, 0, 0 }
 
1017
};
 
1018
 
 
1019
static const char *epinq_help =
 
1020
        "Usage:\n"
 
1021
        "\tspinq\n";
 
1022
 
 
1023
static void cmd_epinq(int dev_id, int argc, char **argv)
 
1024
{
 
1025
        int opt, dd;
 
1026
 
 
1027
        for_each_opt(opt, epinq_options, NULL) {
 
1028
                switch (opt) {
 
1029
                default:
 
1030
                        printf(epinq_help);
 
1031
                        return;
 
1032
                }
 
1033
        }
 
1034
 
 
1035
        if (dev_id < 0)
 
1036
                dev_id = hci_get_route(NULL);
 
1037
 
 
1038
        dd = hci_open_dev(dev_id);
 
1039
        if (dd < 0) {
 
1040
                perror("Device open failed");
 
1041
                exit(EXIT_FAILURE);
 
1042
        }
 
1043
 
 
1044
        if (hci_send_cmd(dd, OGF_LINK_CTL,
 
1045
                                OCF_EXIT_PERIODIC_INQUIRY, 0, NULL) < 0) {
 
1046
                perror("Exit periodic inquiry failed");
 
1047
                exit(EXIT_FAILURE);
 
1048
        }
 
1049
 
 
1050
        hci_close_dev(dd);
 
1051
}
 
1052
 
 
1053
/* Send arbitrary HCI commands */
 
1054
 
 
1055
static struct option cmd_options[] = {
 
1056
        { "help",       0, 0, 'h' },
 
1057
        { 0, 0, 0, 0 }
 
1058
};
 
1059
 
 
1060
static const char *cmd_help =
 
1061
        "Usage:\n"
 
1062
        "\tcmd <ogf> <ocf> [parameters]\n"
 
1063
        "Example:\n"
 
1064
        "\tcmd 0x03 0x0013 0x41 0x42 0x43 0x44\n";
 
1065
 
 
1066
static void cmd_cmd(int dev_id, int argc, char **argv)
 
1067
{
 
1068
        unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr = buf;
 
1069
        struct hci_filter flt;
 
1070
        hci_event_hdr *hdr;
 
1071
        int i, opt, len, dd;
 
1072
        uint16_t ocf;
 
1073
        uint8_t ogf;
 
1074
 
 
1075
        for_each_opt(opt, cmd_options, NULL) {
 
1076
                switch (opt) {
 
1077
                default:
 
1078
                        printf(cmd_help);
 
1079
                        return;
 
1080
                }
 
1081
        }
 
1082
        argc -= optind;
 
1083
        argv += optind;
 
1084
 
 
1085
        if (argc < 2) {
 
1086
                printf(cmd_help);
 
1087
                return;
 
1088
        }
 
1089
 
 
1090
        if (dev_id < 0)
 
1091
                dev_id = hci_get_route(NULL);
 
1092
 
 
1093
        errno = 0;
 
1094
        ogf = strtol(argv[0], NULL, 16);
 
1095
        ocf = strtol(argv[1], NULL, 16);
 
1096
        if (errno == ERANGE || (ogf > 0x3f) || (ocf > 0x3ff)) {
 
1097
                printf(cmd_help);
 
1098
                return;
 
1099
        }
 
1100
 
 
1101
        for (i = 2, len = 0; i < argc && len < sizeof(buf); i++, len++)
 
1102
                *ptr++ = (uint8_t) strtol(argv[i], NULL, 16);
 
1103
 
 
1104
        dd = hci_open_dev(dev_id);
 
1105
        if (dd < 0) {
 
1106
                perror("Device open failed");
 
1107
                exit(EXIT_FAILURE);
 
1108
        }
 
1109
 
 
1110
        /* Setup filter */
 
1111
        hci_filter_clear(&flt);
 
1112
        hci_filter_set_ptype(HCI_EVENT_PKT, &flt);
 
1113
        hci_filter_all_events(&flt);
 
1114
        if (setsockopt(dd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {
 
1115
                perror("HCI filter setup failed");
 
1116
                exit(EXIT_FAILURE);
 
1117
        }
 
1118
 
 
1119
        printf("< HCI Command: ogf 0x%02x, ocf 0x%04x, plen %d\n", ogf, ocf, len);
 
1120
        hex_dump("  ", 20, buf, len); fflush(stdout);
 
1121
 
 
1122
        if (hci_send_cmd(dd, ogf, ocf, len, buf) < 0) {
 
1123
                perror("Send failed");
 
1124
                exit(EXIT_FAILURE);
 
1125
        }
 
1126
 
 
1127
        len = read(dd, buf, sizeof(buf));
 
1128
        if (len < 0) {
 
1129
                perror("Read failed");
 
1130
                exit(EXIT_FAILURE);
 
1131
        }
 
1132
 
 
1133
        hdr = (void *)(buf + 1);
 
1134
        ptr = buf + (1 + HCI_EVENT_HDR_SIZE);
 
1135
        len -= (1 + HCI_EVENT_HDR_SIZE);
 
1136
 
 
1137
        printf("> HCI Event: 0x%02x plen %d\n", hdr->evt, hdr->plen);
 
1138
        hex_dump("  ", 20, ptr, len); fflush(stdout);
 
1139
 
 
1140
        hci_close_dev(dd);
 
1141
}
 
1142
 
 
1143
/* Display active connections */
 
1144
 
 
1145
static struct option con_options[] = {
 
1146
        { "help",       0, 0, 'h' },
 
1147
        { 0, 0, 0, 0 }
 
1148
};
 
1149
 
 
1150
static const char *con_help =
 
1151
        "Usage:\n"
 
1152
        "\tcon\n";
 
1153
 
 
1154
static void cmd_con(int dev_id, int argc, char **argv)
 
1155
{
 
1156
        int opt;
 
1157
 
 
1158
        for_each_opt(opt, con_options, NULL) {
 
1159
                switch (opt) {
 
1160
                default:
 
1161
                        printf(con_help);
 
1162
                        return;
 
1163
                }
 
1164
        }
 
1165
 
 
1166
        printf("Connections:\n");
 
1167
 
 
1168
        hci_for_each_dev(HCI_UP, conn_list, dev_id);
 
1169
}
 
1170
 
 
1171
/* Create connection */
 
1172
 
 
1173
static struct option cc_options[] = {
 
1174
        { "help",       0, 0, 'h' },
 
1175
        { "role",       1, 0, 'r' },
 
1176
        { "ptype",      1, 0, 'p' },
 
1177
        { 0, 0, 0, 0 }
 
1178
};
 
1179
 
 
1180
static const char *cc_help =
 
1181
        "Usage:\n"
 
1182
        "\tcc [--role=m|s] [--ptype=pkt_types] <bdaddr>\n"
 
1183
        "Example:\n"
 
1184
        "\tcc --ptype=dm1,dh3,dh5 01:02:03:04:05:06\n"
 
1185
        "\tcc --role=m 01:02:03:04:05:06\n";
 
1186
 
 
1187
static void cmd_cc(int dev_id, int argc, char **argv)
 
1188
{
 
1189
        bdaddr_t bdaddr;
 
1190
        uint16_t handle;
 
1191
        uint8_t role;
 
1192
        unsigned int ptype;
 
1193
        int dd, opt;
 
1194
 
 
1195
        role = 0x01;
 
1196
        ptype = HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5;
 
1197
 
 
1198
        for_each_opt(opt, cc_options, NULL) {
 
1199
                switch (opt) {
 
1200
                case 'p':
 
1201
                        hci_strtoptype(optarg, &ptype);
 
1202
                        break;
 
1203
 
 
1204
                case 'r':
 
1205
                        role = optarg[0] == 'm' ? 0 : 1;
 
1206
                        break;
 
1207
 
 
1208
                default:
 
1209
                        printf(cc_help);
 
1210
                        return;
 
1211
                }
 
1212
        }
 
1213
        argc -= optind;
 
1214
        argv += optind;
 
1215
 
 
1216
        if (argc < 1) {
 
1217
                printf(cc_help);
 
1218
                return;
 
1219
        }
 
1220
 
 
1221
        str2ba(argv[0], &bdaddr);
 
1222
 
 
1223
        if (dev_id < 0) {
 
1224
                dev_id = hci_get_route(&bdaddr);
 
1225
                if (dev_id < 0) {
 
1226
                        fprintf(stderr, "Device is not available.\n");
 
1227
                        exit(1);
 
1228
                }
 
1229
        }
 
1230
 
 
1231
        dd = hci_open_dev(dev_id);
 
1232
        if (dd < 0) {
 
1233
                perror("HCI device open failed");
 
1234
                exit(1);
 
1235
        }
 
1236
 
 
1237
        if (hci_create_connection(dd, &bdaddr, htobs(ptype),
 
1238
                                htobs(0x0000), role, &handle, 25000) < 0)
 
1239
                perror("Can't create connection");
 
1240
 
 
1241
        hci_close_dev(dd);
 
1242
}
 
1243
 
 
1244
/* Close connection */
 
1245
 
 
1246
static struct option dc_options[] = {
 
1247
        { "help",       0, 0, 'h' },
 
1248
        { 0, 0, 0, 0 }
 
1249
};
 
1250
 
 
1251
static const char *dc_help =
 
1252
        "Usage:\n"
 
1253
        "\tdc <bdaddr> [reason]\n";
 
1254
 
 
1255
static void cmd_dc(int dev_id, int argc, char **argv)
 
1256
{
 
1257
        struct hci_conn_info_req *cr;
 
1258
        bdaddr_t bdaddr;
 
1259
        uint8_t reason;
 
1260
        int opt, dd;
 
1261
 
 
1262
        for_each_opt(opt, dc_options, NULL) {
 
1263
                switch (opt) {
 
1264
                default:
 
1265
                        printf(dc_help);
 
1266
                        return;
 
1267
                }
 
1268
        }
 
1269
        argc -= optind;
 
1270
        argv += optind;
 
1271
 
 
1272
        if (argc < 1) {
 
1273
                printf(dc_help);
 
1274
                return;
 
1275
        }
 
1276
 
 
1277
        str2ba(argv[0], &bdaddr);
 
1278
        reason = (argc > 1) ? atoi(argv[1]) : HCI_OE_USER_ENDED_CONNECTION;
 
1279
 
 
1280
        if (dev_id < 0) {
 
1281
                dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
 
1282
                if (dev_id < 0) {
 
1283
                        fprintf(stderr, "Not connected.\n");
 
1284
                        exit(1);
 
1285
                }
 
1286
        }
 
1287
 
 
1288
        dd = hci_open_dev(dev_id);
 
1289
        if (dd < 0) {
 
1290
                perror("HCI device open failed");
 
1291
                exit(1);
 
1292
        }
 
1293
 
 
1294
        cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
 
1295
        if (!cr) {
 
1296
                perror("Can't allocate memory");
 
1297
                exit(1);
 
1298
        }
 
1299
 
 
1300
        bacpy(&cr->bdaddr, &bdaddr);
 
1301
        cr->type = ACL_LINK;
 
1302
        if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
 
1303
                perror("Get connection info failed");
 
1304
                exit(1);
 
1305
        }
 
1306
 
 
1307
        if (hci_disconnect(dd, htobs(cr->conn_info->handle),
 
1308
                                                reason, 10000) < 0)
 
1309
                perror("Disconnect failed");
 
1310
 
 
1311
        free(cr);
 
1312
 
 
1313
        hci_close_dev(dd);
 
1314
}
 
1315
 
 
1316
/* Role switch */
 
1317
 
 
1318
static struct option sr_options[] = {
 
1319
        { "help",       0, 0, 'h' },
 
1320
        { 0, 0, 0, 0 }
 
1321
};
 
1322
 
 
1323
static const char *sr_help =
 
1324
        "Usage:\n"
 
1325
        "\tsr <bdaddr> <role>\n";
 
1326
 
 
1327
static void cmd_sr(int dev_id, int argc, char **argv)
 
1328
{
 
1329
        bdaddr_t bdaddr;
 
1330
        uint8_t role;
 
1331
        int opt, dd;
 
1332
 
 
1333
        for_each_opt(opt, sr_options, NULL) {
 
1334
                switch (opt) {
 
1335
                default:
 
1336
                        printf(sr_help);
 
1337
                        return;
 
1338
                }
 
1339
        }
 
1340
        argc -= optind;
 
1341
        argv += optind;
 
1342
 
 
1343
        if (argc < 2) {
 
1344
                printf(sr_help);
 
1345
                return;
 
1346
        }
 
1347
 
 
1348
        str2ba(argv[0], &bdaddr);
 
1349
        switch (argv[1][0]) {
 
1350
        case 'm':
 
1351
                role = 0;
 
1352
                break;
 
1353
        case 's':
 
1354
                role = 1;
 
1355
                break;
 
1356
        default:
 
1357
                role = atoi(argv[1]);
 
1358
                break;
 
1359
        }
 
1360
 
 
1361
        if (dev_id < 0) {
 
1362
                dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
 
1363
                if (dev_id < 0) {
 
1364
                        fprintf(stderr, "Not connected.\n");
 
1365
                        exit(1);
 
1366
                }
 
1367
        }
 
1368
 
 
1369
        dd = hci_open_dev(dev_id);
 
1370
        if (dd < 0) {
 
1371
                perror("HCI device open failed");
 
1372
                exit(1);
 
1373
        }
 
1374
 
 
1375
        if (hci_switch_role(dd, &bdaddr, role, 10000) < 0) {
 
1376
                perror("Switch role request failed");
 
1377
                exit(1);
 
1378
        }
 
1379
 
 
1380
        hci_close_dev(dd);
 
1381
}
 
1382
 
 
1383
/* Read RSSI */
 
1384
 
 
1385
static struct option rssi_options[] = {
 
1386
        { "help",       0, 0, 'h' },
 
1387
        { 0, 0, 0, 0 }
 
1388
};
 
1389
 
 
1390
static const char *rssi_help =
 
1391
        "Usage:\n"
 
1392
        "\trssi <bdaddr>\n";
 
1393
 
 
1394
static void cmd_rssi(int dev_id, int argc, char **argv)
 
1395
{
 
1396
        struct hci_conn_info_req *cr;
 
1397
        bdaddr_t bdaddr;
 
1398
        int8_t rssi;
 
1399
        int opt, dd;
 
1400
 
 
1401
        for_each_opt(opt, rssi_options, NULL) {
 
1402
                switch (opt) {
 
1403
                default:
 
1404
                        printf(rssi_help);
 
1405
                        return;
 
1406
                }
 
1407
        }
 
1408
        argc -= optind;
 
1409
        argv += optind;
 
1410
 
 
1411
        if (argc < 1) {
 
1412
                printf(rssi_help);
 
1413
                return;
 
1414
        }
 
1415
 
 
1416
        str2ba(argv[0], &bdaddr);
 
1417
 
 
1418
        if (dev_id < 0) {
 
1419
                dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
 
1420
                if (dev_id < 0) {
 
1421
                        fprintf(stderr, "Not connected.\n");
 
1422
                        exit(1);
 
1423
                }
 
1424
        }
 
1425
 
 
1426
        dd = hci_open_dev(dev_id);
 
1427
        if (dd < 0) {
 
1428
                perror("HCI device open failed");
 
1429
                exit(1);
 
1430
        }
 
1431
 
 
1432
        cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
 
1433
        if (!cr) {
 
1434
                perror("Can't allocate memory");
 
1435
                exit(1);
 
1436
        }
 
1437
 
 
1438
        bacpy(&cr->bdaddr, &bdaddr);
 
1439
        cr->type = ACL_LINK;
 
1440
        if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
 
1441
                perror("Get connection info failed");
 
1442
                exit(1);
 
1443
        }
 
1444
 
 
1445
        if (hci_read_rssi(dd, htobs(cr->conn_info->handle), &rssi, 1000) < 0) {
 
1446
                perror("Read RSSI failed");
 
1447
                exit(1);
 
1448
        }
 
1449
 
 
1450
        printf("RSSI return value: %d\n", rssi);
 
1451
 
 
1452
        free(cr);
 
1453
 
 
1454
        hci_close_dev(dd);
 
1455
}
 
1456
 
 
1457
/* Get link quality */
 
1458
 
 
1459
static struct option lq_options[] = {
 
1460
        { "help",       0, 0, 'h' },
 
1461
        { 0, 0, 0, 0 }
 
1462
};
 
1463
 
 
1464
static const char *lq_help =
 
1465
        "Usage:\n"
 
1466
        "\tlq <bdaddr>\n";
 
1467
 
 
1468
static void cmd_lq(int dev_id, int argc, char **argv)
 
1469
{
 
1470
        struct hci_conn_info_req *cr;
 
1471
        bdaddr_t bdaddr;
 
1472
        uint8_t lq;
 
1473
        int opt, dd;
 
1474
 
 
1475
        for_each_opt(opt, lq_options, NULL) {
 
1476
                switch (opt) {
 
1477
                default:
 
1478
                        printf(lq_help);
 
1479
                        return;
 
1480
                }
 
1481
        }
 
1482
        argc -= optind;
 
1483
        argv += optind;
 
1484
 
 
1485
        if (argc < 1) {
 
1486
                printf(lq_help);
 
1487
                return;
 
1488
        }
 
1489
 
 
1490
        str2ba(argv[0], &bdaddr);
 
1491
 
 
1492
        if (dev_id < 0) {
 
1493
                dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
 
1494
                if (dev_id < 0) {
 
1495
                        fprintf(stderr, "Not connected.\n");
 
1496
                        exit(1);
 
1497
                }
 
1498
        }
 
1499
 
 
1500
        dd = hci_open_dev(dev_id);
 
1501
        if (dd < 0) {
 
1502
                perror("HCI device open failed");
 
1503
                exit(1);
 
1504
        }
 
1505
 
 
1506
        cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
 
1507
        if (!cr) {
 
1508
                perror("Can't allocate memory");
 
1509
                exit(1);
 
1510
        }
 
1511
 
 
1512
        bacpy(&cr->bdaddr, &bdaddr);
 
1513
        cr->type = ACL_LINK;
 
1514
        if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
 
1515
                perror("Get connection info failed");
 
1516
                exit(1);
 
1517
        }
 
1518
 
 
1519
        if (hci_read_link_quality(dd, htobs(cr->conn_info->handle), &lq, 1000) < 0) {
 
1520
                perror("HCI read_link_quality request failed");
 
1521
                exit(1);
 
1522
        }
 
1523
 
 
1524
        printf("Link quality: %d\n", lq);
 
1525
 
 
1526
        free(cr);
 
1527
 
 
1528
        hci_close_dev(dd);
 
1529
}
 
1530
 
 
1531
/* Get transmit power level */
 
1532
 
 
1533
static struct option tpl_options[] = {
 
1534
        { "help",       0, 0, 'h' },
 
1535
        { 0, 0, 0, 0 }
 
1536
};
 
1537
 
 
1538
static const char *tpl_help =
 
1539
        "Usage:\n"
 
1540
        "\ttpl <bdaddr> [type]\n";
 
1541
 
 
1542
static void cmd_tpl(int dev_id, int argc, char **argv)
 
1543
{
 
1544
        struct hci_conn_info_req *cr;
 
1545
        bdaddr_t bdaddr;
 
1546
        uint8_t type;
 
1547
        int8_t level;
 
1548
        int opt, dd;
 
1549
 
 
1550
        for_each_opt(opt, tpl_options, NULL) {
 
1551
                switch (opt) {
 
1552
                default:
 
1553
                        printf(tpl_help);
 
1554
                        return;
 
1555
                }
 
1556
        }
 
1557
        argc -= optind;
 
1558
        argv += optind;
 
1559
 
 
1560
        if (argc < 1) {
 
1561
                printf(tpl_help);
 
1562
                return;
 
1563
        }
 
1564
 
 
1565
        str2ba(argv[0], &bdaddr);
 
1566
        type = (argc > 1) ? atoi(argv[1]) : 0;
 
1567
 
 
1568
        if (dev_id < 0) {
 
1569
                dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
 
1570
                if (dev_id < 0) {
 
1571
                        fprintf(stderr, "Not connected.\n");
 
1572
                        exit(1);
 
1573
                }
 
1574
        }
 
1575
 
 
1576
        dd = hci_open_dev(dev_id);
 
1577
        if (dd < 0) {
 
1578
                perror("HCI device open failed");
 
1579
                exit(1);
 
1580
        }
 
1581
 
 
1582
        cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
 
1583
        if (!cr) {
 
1584
                perror("Can't allocate memory");
 
1585
                exit(1);
 
1586
        }
 
1587
 
 
1588
        bacpy(&cr->bdaddr, &bdaddr);
 
1589
        cr->type = ACL_LINK;
 
1590
        if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
 
1591
                perror("Get connection info failed");
 
1592
                exit(1);
 
1593
        }
 
1594
 
 
1595
        if (hci_read_transmit_power_level(dd, htobs(cr->conn_info->handle), type, &level, 1000) < 0) {
 
1596
                perror("HCI read transmit power level request failed");
 
1597
                exit(1);
 
1598
        }
 
1599
 
 
1600
        printf("%s transmit power level: %d\n",
 
1601
                (type == 0) ? "Current" : "Maximum", level);
 
1602
 
 
1603
        free(cr);
 
1604
 
 
1605
        hci_close_dev(dd);
 
1606
}
 
1607
 
 
1608
/* Get AFH channel map */
 
1609
 
 
1610
static struct option afh_options[] = {
 
1611
        { "help",       0, 0, 'h' },
 
1612
        { 0, 0, 0, 0 }
 
1613
};
 
1614
 
 
1615
static const char *afh_help =
 
1616
        "Usage:\n"
 
1617
        "\tafh <bdaddr>\n";
 
1618
 
 
1619
static void cmd_afh(int dev_id, int argc, char **argv)
 
1620
{
 
1621
        struct hci_conn_info_req *cr;
 
1622
        bdaddr_t bdaddr;
 
1623
        uint16_t handle;
 
1624
        uint8_t mode, map[10];
 
1625
        int opt, dd;
 
1626
 
 
1627
        for_each_opt(opt, afh_options, NULL) {
 
1628
                switch (opt) {
 
1629
                default:
 
1630
                        printf(afh_help);
 
1631
                        return;
 
1632
                }
 
1633
        }
 
1634
        argc -= optind;
 
1635
        argv += optind;
 
1636
 
 
1637
        if (argc < 1) {
 
1638
                printf(afh_help);
 
1639
                return;
 
1640
        }
 
1641
 
 
1642
        str2ba(argv[0], &bdaddr);
 
1643
 
 
1644
        if (dev_id < 0) {
 
1645
                dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
 
1646
                if (dev_id < 0) {
 
1647
                        fprintf(stderr, "Not connected.\n");
 
1648
                        exit(1);
 
1649
                }
 
1650
        }
 
1651
 
 
1652
        dd = hci_open_dev(dev_id);
 
1653
        if (dd < 0) {
 
1654
                perror("HCI device open failed");
 
1655
                exit(1);
 
1656
        }
 
1657
 
 
1658
        cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
 
1659
        if (!cr) {
 
1660
                perror("Can't allocate memory");
 
1661
                exit(1);
 
1662
        }
 
1663
 
 
1664
        bacpy(&cr->bdaddr, &bdaddr);
 
1665
        cr->type = ACL_LINK;
 
1666
        if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
 
1667
                perror("Get connection info failed");
 
1668
                exit(1);
 
1669
        }
 
1670
 
 
1671
        handle = htobs(cr->conn_info->handle);
 
1672
 
 
1673
        if (hci_read_afh_map(dd, handle, &mode, map, 1000) < 0) {
 
1674
                perror("HCI read AFH map request failed");
 
1675
                exit(1);
 
1676
        }
 
1677
 
 
1678
        if (mode == 0x01) {
 
1679
                int i;
 
1680
                printf("AFH map: 0x");
 
1681
                for (i = 0; i < 10; i++)
 
1682
                        printf("%02x", map[i]);
 
1683
                printf("\n");
 
1684
        } else
 
1685
                printf("AFH disabled\n");
 
1686
 
 
1687
        free(cr);
 
1688
 
 
1689
        hci_close_dev(dd);
 
1690
}
 
1691
 
 
1692
/* Set connection packet type */
 
1693
 
 
1694
static struct option cpt_options[] = {
 
1695
        { "help",       0, 0, 'h' },
 
1696
        { 0, 0, 0, 0 }
 
1697
};
 
1698
 
 
1699
static const char *cpt_help =
 
1700
        "Usage:\n"
 
1701
        "\tcpt <bdaddr> <packet_types>\n";
 
1702
 
 
1703
static void cmd_cpt(int dev_id, int argc, char **argv)
 
1704
{
 
1705
        struct hci_conn_info_req *cr;
 
1706
        struct hci_request rq;
 
1707
        set_conn_ptype_cp cp;
 
1708
        evt_conn_ptype_changed rp;
 
1709
        bdaddr_t bdaddr;
 
1710
        unsigned int ptype;
 
1711
        int dd, opt;
 
1712
 
 
1713
        for_each_opt(opt, cpt_options, NULL) {
 
1714
                switch (opt) {
 
1715
                default:
 
1716
                        printf(cpt_help);
 
1717
                        return;
 
1718
                }
 
1719
        }
 
1720
        argc -= optind;
 
1721
        argv += optind;
 
1722
 
 
1723
        if (argc < 2) {
 
1724
                printf(cpt_help);
 
1725
                return;
 
1726
        }
 
1727
 
 
1728
        str2ba(argv[0], &bdaddr);
 
1729
        hci_strtoptype(argv[1], &ptype);
 
1730
 
 
1731
        if (dev_id < 0) {
 
1732
                dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
 
1733
                if (dev_id < 0) {
 
1734
                        fprintf(stderr, "Not connected.\n");
 
1735
                        exit(1);
 
1736
                }
 
1737
        }
 
1738
 
 
1739
        dd = hci_open_dev(dev_id);
 
1740
        if (dd < 0) {
 
1741
                perror("HCI device open failed");
 
1742
                exit(1);
 
1743
        }
 
1744
 
 
1745
        cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
 
1746
        if (!cr) {
 
1747
                perror("Can't allocate memory");
 
1748
                exit(1);
 
1749
        }
 
1750
 
 
1751
        bacpy(&cr->bdaddr, &bdaddr);
 
1752
        cr->type = ACL_LINK;
 
1753
        if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
 
1754
                perror("Get connection info failed");
 
1755
                exit(1);
 
1756
        }
 
1757
 
 
1758
        cp.handle   = htobs(cr->conn_info->handle);
 
1759
        cp.pkt_type = ptype;
 
1760
 
 
1761
        memset(&rq, 0, sizeof(rq));
 
1762
        rq.ogf    = OGF_LINK_CTL;
 
1763
        rq.ocf    = OCF_SET_CONN_PTYPE;
 
1764
        rq.cparam = &cp;
 
1765
        rq.clen   = SET_CONN_PTYPE_CP_SIZE;
 
1766
        rq.rparam = &rp;
 
1767
        rq.rlen   = EVT_CONN_PTYPE_CHANGED_SIZE;
 
1768
        rq.event  = EVT_CONN_PTYPE_CHANGED;
 
1769
 
 
1770
        if (hci_send_req(dd, &rq, 100) < 0) {
 
1771
                perror("Packet type change failed");
 
1772
                exit(1);
 
1773
        }
 
1774
 
 
1775
        free(cr);
 
1776
 
 
1777
        hci_close_dev(dd);
 
1778
}
 
1779
 
 
1780
/* Get/Set link policy settings */
 
1781
 
 
1782
static struct option lp_options[] = {
 
1783
        { "help",       0, 0, 'h' },
 
1784
        { 0, 0, 0, 0 }
 
1785
};
 
1786
 
 
1787
static const char *lp_help =
 
1788
        "Usage:\n"
 
1789
        "\tlp <bdaddr> [link policy]\n";
 
1790
 
 
1791
static void cmd_lp(int dev_id, int argc, char **argv)
 
1792
{
 
1793
        struct hci_conn_info_req *cr;
 
1794
        bdaddr_t bdaddr;
 
1795
        uint16_t policy;
 
1796
        int opt, dd;
 
1797
 
 
1798
        for_each_opt(opt, lp_options, NULL) {
 
1799
                switch (opt) {
 
1800
                default:
 
1801
                        printf(lp_help);
 
1802
                        return;
 
1803
                }
 
1804
        }
 
1805
        argc -= optind;
 
1806
        argv += optind;
 
1807
 
 
1808
        if (argc < 1) {
 
1809
                printf(lp_help);
 
1810
                return;
 
1811
        }
 
1812
 
 
1813
        str2ba(argv[0], &bdaddr);
 
1814
 
 
1815
        if (dev_id < 0) {
 
1816
                dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
 
1817
                if (dev_id < 0) {
 
1818
                        fprintf(stderr, "Not connected.\n");
 
1819
                        exit(1);
 
1820
                }
 
1821
        }
 
1822
 
 
1823
        dd = hci_open_dev(dev_id);
 
1824
        if (dd < 0) {
 
1825
                perror("HCI device open failed");
 
1826
                exit(1);
 
1827
        }
 
1828
 
 
1829
        cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
 
1830
        if (!cr) {
 
1831
                perror("Can't allocate memory");
 
1832
                exit(1);
 
1833
        }
 
1834
 
 
1835
        bacpy(&cr->bdaddr, &bdaddr);
 
1836
        cr->type = ACL_LINK;
 
1837
        if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
 
1838
                perror("Get connection info failed");
 
1839
                exit(1);
 
1840
        }
 
1841
 
 
1842
        if (argc == 1) {
 
1843
                char *str;
 
1844
                if (hci_read_link_policy(dd, htobs(cr->conn_info->handle),
 
1845
                                                        &policy, 1000) < 0) {
 
1846
                        perror("HCI read_link_policy_settings request failed");
 
1847
                        exit(1);
 
1848
                }
 
1849
 
 
1850
                policy = btohs(policy);
 
1851
                str = hci_lptostr(policy);
 
1852
                if (str) {
 
1853
                        printf("Link policy settings: %s\n", str);
 
1854
                        bt_free(str);
 
1855
                } else {
 
1856
                        fprintf(stderr, "Invalig settings\n");
 
1857
                        exit(1);
 
1858
                }
 
1859
        } else {
 
1860
                unsigned int val;
 
1861
                if (hci_strtolp(argv[1], &val) < 0) {
 
1862
                        fprintf(stderr, "Invalig arguments\n");
 
1863
                        exit(1);
 
1864
                }
 
1865
                policy = val;
 
1866
 
 
1867
                if (hci_write_link_policy(dd, htobs(cr->conn_info->handle),
 
1868
                                                htobs(policy), 1000) < 0) {
 
1869
                        perror("HCI write_link_policy_settings request failed");
 
1870
                        exit(1);
 
1871
                }
 
1872
        }
 
1873
 
 
1874
        free(cr);
 
1875
 
 
1876
        hci_close_dev(dd);
 
1877
}
 
1878
 
 
1879
/* Get/Set link supervision timeout */
 
1880
 
 
1881
static struct option lst_options[] = {
 
1882
        { "help",       0, 0, 'h' },
 
1883
        { 0, 0, 0, 0 }
 
1884
};
 
1885
 
 
1886
static const char *lst_help =
 
1887
        "Usage:\n"
 
1888
        "\tlst <bdaddr> [new value in slots]\n";
 
1889
 
 
1890
static void cmd_lst(int dev_id, int argc, char **argv)
 
1891
{
 
1892
        struct hci_conn_info_req *cr;
 
1893
        bdaddr_t bdaddr;
 
1894
        uint16_t timeout;
 
1895
        int opt, dd;
 
1896
 
 
1897
        for_each_opt(opt, lst_options, NULL) {
 
1898
                switch (opt) {
 
1899
                default:
 
1900
                        printf(lst_help);
 
1901
                        return;
 
1902
                }
 
1903
        }
 
1904
        argc -= optind;
 
1905
        argv += optind;
 
1906
 
 
1907
        if (argc < 1) {
 
1908
                printf(lst_help);
 
1909
                return;
 
1910
        }
 
1911
 
 
1912
        str2ba(argv[0], &bdaddr);
 
1913
 
 
1914
        if (dev_id < 0) {
 
1915
                dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
 
1916
                if (dev_id < 0) {
 
1917
                        fprintf(stderr, "Not connected.\n");
 
1918
                        exit(1);
 
1919
                }
 
1920
        }
 
1921
 
 
1922
        dd = hci_open_dev(dev_id);
 
1923
        if (dd < 0) {
 
1924
                perror("HCI device open failed");
 
1925
                exit(1);
 
1926
        }
 
1927
 
 
1928
        cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
 
1929
        if (!cr) {
 
1930
                perror("Can't allocate memory");
 
1931
                exit(1);
 
1932
        }
 
1933
 
 
1934
        bacpy(&cr->bdaddr, &bdaddr);
 
1935
        cr->type = ACL_LINK;
 
1936
        if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
 
1937
                perror("Get connection info failed");
 
1938
                exit(1);
 
1939
        }
 
1940
 
 
1941
        if (argc == 1) {
 
1942
                if (hci_read_link_supervision_timeout(dd, htobs(cr->conn_info->handle),
 
1943
                                                        &timeout, 1000) < 0) {
 
1944
                        perror("HCI read_link_supervision_timeout request failed");
 
1945
                        exit(1);
 
1946
                }
 
1947
 
 
1948
                timeout = btohs(timeout);
 
1949
 
 
1950
                if (timeout)
 
1951
                        printf("Link supervision timeout: %u slots (%.2f msec)\n",
 
1952
                                timeout, (float) timeout * 0.625);
 
1953
                else
 
1954
                        printf("Link supervision timeout never expires\n");
 
1955
        } else {
 
1956
                timeout = strtol(argv[1], NULL, 10);
 
1957
 
 
1958
                if (hci_write_link_supervision_timeout(dd, htobs(cr->conn_info->handle),
 
1959
                                                        htobs(timeout), 1000) < 0) {
 
1960
                        perror("HCI write_link_supervision_timeout request failed");
 
1961
                        exit(1);
 
1962
                }
 
1963
        }
 
1964
 
 
1965
        free(cr);
 
1966
 
 
1967
        hci_close_dev(dd);
 
1968
}
 
1969
 
 
1970
/* Request authentication */
 
1971
 
 
1972
static struct option auth_options[] = {
 
1973
        { "help",       0, 0, 'h' },
 
1974
        { 0, 0, 0, 0 }
 
1975
};
 
1976
 
 
1977
static const char *auth_help =
 
1978
        "Usage:\n"
 
1979
        "\tauth <bdaddr>\n";
 
1980
 
 
1981
static void cmd_auth(int dev_id, int argc, char **argv)
 
1982
{
 
1983
        struct hci_conn_info_req *cr;
 
1984
        bdaddr_t bdaddr;
 
1985
        int opt, dd;
 
1986
 
 
1987
        for_each_opt(opt, auth_options, NULL) {
 
1988
                switch (opt) {
 
1989
                default:
 
1990
                        printf(auth_help);
 
1991
                        return;
 
1992
                }
 
1993
        }
 
1994
        argc -= optind;
 
1995
        argv += optind;
 
1996
 
 
1997
        if (argc < 1) {
 
1998
                printf(auth_help);
 
1999
                return;
 
2000
        }
 
2001
 
 
2002
        str2ba(argv[0], &bdaddr);
 
2003
 
 
2004
        if (dev_id < 0) {
 
2005
                dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
 
2006
                if (dev_id < 0) {
 
2007
                        fprintf(stderr, "Not connected.\n");
 
2008
                        exit(1);
 
2009
                }
 
2010
        }
 
2011
 
 
2012
        dd = hci_open_dev(dev_id);
 
2013
        if (dd < 0) {
 
2014
                perror("HCI device open failed");
 
2015
                exit(1);
 
2016
        }
 
2017
 
 
2018
        cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
 
2019
        if (!cr) {
 
2020
                perror("Can't allocate memory");
 
2021
                exit(1);
 
2022
        }
 
2023
 
 
2024
        bacpy(&cr->bdaddr, &bdaddr);
 
2025
        cr->type = ACL_LINK;
 
2026
        if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
 
2027
                perror("Get connection info failed");
 
2028
                exit(1);
 
2029
        }
 
2030
 
 
2031
        if (hci_authenticate_link(dd, htobs(cr->conn_info->handle), 25000) < 0) {
 
2032
                perror("HCI authentication request failed");
 
2033
                exit(1);
 
2034
        }
 
2035
 
 
2036
        free(cr);
 
2037
 
 
2038
        hci_close_dev(dd);
 
2039
}
 
2040
 
 
2041
/* Activate encryption */
 
2042
 
 
2043
static struct option enc_options[] = {
 
2044
        { "help",       0, 0, 'h' },
 
2045
        { 0, 0, 0, 0 }
 
2046
};
 
2047
 
 
2048
static const char *enc_help =
 
2049
        "Usage:\n"
 
2050
        "\tenc <bdaddr> [encrypt enable]\n";
 
2051
 
 
2052
static void cmd_enc(int dev_id, int argc, char **argv)
 
2053
{
 
2054
        struct hci_conn_info_req *cr;
 
2055
        bdaddr_t bdaddr;
 
2056
        uint8_t encrypt;
 
2057
        int opt, dd;
 
2058
 
 
2059
        for_each_opt(opt, enc_options, NULL) {
 
2060
                switch (opt) {
 
2061
                default:
 
2062
                        printf(enc_help);
 
2063
                        return;
 
2064
                }
 
2065
        }
 
2066
        argc -= optind;
 
2067
        argv += optind;
 
2068
 
 
2069
        if (argc < 1) {
 
2070
                printf(enc_help);
 
2071
                return;
 
2072
        }
 
2073
 
 
2074
        str2ba(argv[0], &bdaddr);
 
2075
 
 
2076
        if (dev_id < 0) {
 
2077
                dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
 
2078
                if (dev_id < 0) {
 
2079
                        fprintf(stderr, "Not connected.\n");
 
2080
                        exit(1);
 
2081
                }
 
2082
        }
 
2083
 
 
2084
        dd = hci_open_dev(dev_id);
 
2085
        if (dd < 0) {
 
2086
                perror("HCI device open failed");
 
2087
                exit(1);
 
2088
        }
 
2089
 
 
2090
        cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
 
2091
        if (!cr) {
 
2092
                perror("Can't allocate memory");
 
2093
                exit(1);
 
2094
        }
 
2095
 
 
2096
        bacpy(&cr->bdaddr, &bdaddr);
 
2097
        cr->type = ACL_LINK;
 
2098
        if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
 
2099
                perror("Get connection info failed");
 
2100
                exit(1);
 
2101
        }
 
2102
 
 
2103
        encrypt = (argc > 1) ? atoi(argv[1]) : 1;
 
2104
 
 
2105
        if (hci_encrypt_link(dd, htobs(cr->conn_info->handle), encrypt, 25000) < 0) {
 
2106
                perror("HCI set encryption request failed");
 
2107
                exit(1);
 
2108
        }
 
2109
 
 
2110
        free(cr);
 
2111
 
 
2112
        hci_close_dev(dd);
 
2113
}
 
2114
 
 
2115
/* Change connection link key */
 
2116
 
 
2117
static struct option key_options[] = {
 
2118
        { "help",       0, 0, 'h' },
 
2119
        { 0, 0, 0, 0 }
 
2120
};
 
2121
 
 
2122
static const char *key_help =
 
2123
        "Usage:\n"
 
2124
        "\tkey <bdaddr>\n";
 
2125
 
 
2126
static void cmd_key(int dev_id, int argc, char **argv)
 
2127
{
 
2128
        struct hci_conn_info_req *cr;
 
2129
        bdaddr_t bdaddr;
 
2130
        int opt, dd;
 
2131
 
 
2132
        for_each_opt(opt, key_options, NULL) {
 
2133
                switch (opt) {
 
2134
                default:
 
2135
                        printf(key_help);
 
2136
                        return;
 
2137
                }
 
2138
        }
 
2139
        argc -= optind;
 
2140
        argv += optind;
 
2141
 
 
2142
        if (argc < 1) {
 
2143
                printf(key_help);
 
2144
                return;
 
2145
        }
 
2146
 
 
2147
        str2ba(argv[0], &bdaddr);
 
2148
 
 
2149
        if (dev_id < 0) {
 
2150
                dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
 
2151
                if (dev_id < 0) {
 
2152
                        fprintf(stderr, "Not connected.\n");
 
2153
                        exit(1);
 
2154
                }
 
2155
        }
 
2156
 
 
2157
        dd = hci_open_dev(dev_id);
 
2158
        if (dd < 0) {
 
2159
                perror("HCI device open failed");
 
2160
                exit(1);
 
2161
        }
 
2162
 
 
2163
        cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
 
2164
        if (!cr) {
 
2165
                perror("Can't allocate memory");
 
2166
                exit(1);
 
2167
        }
 
2168
 
 
2169
        bacpy(&cr->bdaddr, &bdaddr);
 
2170
        cr->type = ACL_LINK;
 
2171
        if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
 
2172
                perror("Get connection info failed");
 
2173
                exit(1);
 
2174
        }
 
2175
 
 
2176
        if (hci_change_link_key(dd, htobs(cr->conn_info->handle), 25000) < 0) {
 
2177
                perror("Changing link key failed");
 
2178
                exit(1);
 
2179
        }
 
2180
 
 
2181
        free(cr);
 
2182
 
 
2183
        hci_close_dev(dd);
 
2184
}
 
2185
 
 
2186
/* Read clock offset */
 
2187
 
 
2188
static struct option clkoff_options[] = {
 
2189
        { "help",       0, 0, 'h' },
 
2190
        { 0, 0, 0, 0 }
 
2191
};
 
2192
 
 
2193
static const char *clkoff_help =
 
2194
        "Usage:\n"
 
2195
        "\tclkoff <bdaddr>\n";
 
2196
 
 
2197
static void cmd_clkoff(int dev_id, int argc, char **argv)
 
2198
{
 
2199
        struct hci_conn_info_req *cr;
 
2200
        bdaddr_t bdaddr;
 
2201
        uint16_t offset;
 
2202
        int opt, dd;
 
2203
 
 
2204
        for_each_opt(opt, clkoff_options, NULL) {
 
2205
                switch (opt) {
 
2206
                default:
 
2207
                        printf(clkoff_help);
 
2208
                        return;
 
2209
                }
 
2210
        }
 
2211
        argc -= optind;
 
2212
        argv += optind;
 
2213
 
 
2214
        if (argc < 1) {
 
2215
                printf(clkoff_help);
 
2216
                return;
 
2217
        }
 
2218
 
 
2219
        str2ba(argv[0], &bdaddr);
 
2220
 
 
2221
        if (dev_id < 0) {
 
2222
                dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
 
2223
                if (dev_id < 0) {
 
2224
                        fprintf(stderr, "Not connected.\n");
 
2225
                        exit(1);
 
2226
                }
 
2227
        }
 
2228
 
 
2229
        dd = hci_open_dev(dev_id);
 
2230
        if (dd < 0) {
 
2231
                perror("HCI device open failed");
 
2232
                exit(1);
 
2233
        }
 
2234
 
 
2235
        cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
 
2236
        if (!cr) {
 
2237
                perror("Can't allocate memory");
 
2238
                exit(1);
 
2239
        }
 
2240
 
 
2241
        bacpy(&cr->bdaddr, &bdaddr);
 
2242
        cr->type = ACL_LINK;
 
2243
        if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
 
2244
                perror("Get connection info failed");
 
2245
                exit(1);
 
2246
        }
 
2247
 
 
2248
        if (hci_read_clock_offset(dd, htobs(cr->conn_info->handle), &offset, 1000) < 0) {
 
2249
                perror("Reading clock offset failed");
 
2250
                exit(1);
 
2251
        }
 
2252
 
 
2253
        printf("Clock offset: 0x%4.4x\n", btohs(offset));
 
2254
 
 
2255
        free(cr);
 
2256
 
 
2257
        hci_close_dev(dd);
 
2258
}
 
2259
 
 
2260
/* Read clock */
 
2261
 
 
2262
static struct option clock_options[] = {
 
2263
        { "help",       0, 0, 'h' },
 
2264
        { 0, 0, 0, 0 }
 
2265
};
 
2266
 
 
2267
static const char *clock_help =
 
2268
        "Usage:\n"
 
2269
        "\tclock [bdaddr] [which clock]\n";
 
2270
 
 
2271
static void cmd_clock(int dev_id, int argc, char **argv)
 
2272
{
 
2273
        struct hci_conn_info_req *cr;
 
2274
        bdaddr_t bdaddr;
 
2275
        uint8_t which;
 
2276
        uint32_t handle, clock;
 
2277
        uint16_t accuracy;
 
2278
        int opt, dd;
 
2279
 
 
2280
        for_each_opt(opt, clock_options, NULL) {
 
2281
                switch (opt) {
 
2282
                default:
 
2283
                        printf(clock_help);
 
2284
                        return;
 
2285
                }
 
2286
        }
 
2287
        argc -= optind;
 
2288
        argv += optind;
 
2289
 
 
2290
        if (argc > 0)
 
2291
                str2ba(argv[0], &bdaddr);
 
2292
        else
 
2293
                bacpy(&bdaddr, BDADDR_ANY);
 
2294
 
 
2295
        if (dev_id < 0 && !bacmp(&bdaddr, BDADDR_ANY))
 
2296
                dev_id = hci_get_route(NULL);
 
2297
 
 
2298
        if (dev_id < 0) {
 
2299
                dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
 
2300
                if (dev_id < 0) {
 
2301
                        fprintf(stderr, "Not connected.\n");
 
2302
                        exit(1);
 
2303
                }
 
2304
        }
 
2305
 
 
2306
        dd = hci_open_dev(dev_id);
 
2307
        if (dd < 0) {
 
2308
                perror("HCI device open failed");
 
2309
                exit(1);
 
2310
        }
 
2311
 
 
2312
        if (bacmp(&bdaddr, BDADDR_ANY)) {
 
2313
                cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
 
2314
                if (!cr) {
 
2315
                        perror("Can't allocate memory");
 
2316
                        exit(1);
 
2317
                }
 
2318
 
 
2319
                bacpy(&cr->bdaddr, &bdaddr);
 
2320
                cr->type = ACL_LINK;
 
2321
                if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
 
2322
                        perror("Get connection info failed");
 
2323
                        free(cr);
 
2324
                        exit(1);
 
2325
                }
 
2326
 
 
2327
                handle = htobs(cr->conn_info->handle);
 
2328
                which = (argc > 1) ? atoi(argv[1]) : 0x01;
 
2329
 
 
2330
                free(cr);
 
2331
        } else {
 
2332
                handle = 0x00;
 
2333
                which = 0x00;
 
2334
        }
 
2335
 
 
2336
        if (hci_read_clock(dd, handle, which, &clock, &accuracy, 1000) < 0) {
 
2337
                perror("Reading clock failed");
 
2338
                exit(1);
 
2339
        }
 
2340
 
 
2341
        accuracy = btohs(accuracy);
 
2342
 
 
2343
        printf("Clock:    0x%4.4x\n", btohl(clock));
 
2344
        printf("Accuracy: %.2f msec\n", (float) accuracy * 0.3125);
 
2345
 
 
2346
        hci_close_dev(dd);
 
2347
}
 
2348
 
 
2349
static struct {
 
2350
        char *cmd;
 
2351
        void (*func)(int dev_id, int argc, char **argv);
 
2352
        char *doc;
 
2353
} command[] = {
 
2354
        { "dev",    cmd_dev,    "Display local devices"                },
 
2355
        { "inq",    cmd_inq,    "Inquire remote devices"               },
 
2356
        { "scan",   cmd_scan,   "Scan for remote devices"              },
 
2357
        { "name",   cmd_name,   "Get name from remote device"          },
 
2358
        { "info",   cmd_info,   "Get information from remote device"   },
 
2359
        { "spinq",  cmd_spinq,  "Start periodic inquiry"               },
 
2360
        { "epinq",  cmd_epinq,  "Exit periodic inquiry"                },
 
2361
        { "cmd",    cmd_cmd,    "Submit arbitrary HCI commands"        },
 
2362
        { "con",    cmd_con,    "Display active connections"           },
 
2363
        { "cc",     cmd_cc,     "Create connection to remote device"   },
 
2364
        { "dc",     cmd_dc,     "Disconnect from remote device"        },
 
2365
        { "sr",     cmd_sr,     "Switch master/slave role"             },
 
2366
        { "cpt",    cmd_cpt,    "Change connection packet type"        },
 
2367
        { "rssi",   cmd_rssi,   "Display connection RSSI"              },
 
2368
        { "lq",     cmd_lq,     "Display link quality"                 },
 
2369
        { "tpl",    cmd_tpl,    "Display transmit power level"         },
 
2370
        { "afh",    cmd_afh,    "Display AFH channel map"              },
 
2371
        { "lp",     cmd_lp,     "Set/display link policy settings"     },
 
2372
        { "lst",    cmd_lst,    "Set/display link supervision timeout" },
 
2373
        { "auth",   cmd_auth,   "Request authentication"               },
 
2374
        { "enc",    cmd_enc,    "Set connection encryption"            },
 
2375
        { "key",    cmd_key,    "Change connection link key"           },
 
2376
        { "clkoff", cmd_clkoff, "Read clock offset"                    },
 
2377
        { "clock",  cmd_clock,  "Read local or remote clock"           },
 
2378
        { NULL, NULL, 0 }
 
2379
};
 
2380
 
 
2381
static void usage(void)
 
2382
{
 
2383
        int i;
 
2384
 
 
2385
        printf("hcitool - HCI Tool ver %s\n", VERSION);
 
2386
        printf("Usage:\n"
 
2387
                "\thcitool [options] <command> [command parameters]\n");
 
2388
        printf("Options:\n"
 
2389
                "\t--help\tDisplay help\n"
 
2390
                "\t-i dev\tHCI device\n");
 
2391
        printf("Commands:\n");
 
2392
        for (i = 0; command[i].cmd; i++)
 
2393
                printf("\t%-4s\t%s\n", command[i].cmd,
 
2394
                command[i].doc);
 
2395
        printf("\n"
 
2396
                "For more information on the usage of each command use:\n"
 
2397
                "\thcitool <command> --help\n" );
 
2398
}
 
2399
 
 
2400
static struct option main_options[] = {
 
2401
        { "help",       0, 0, 'h' },
 
2402
        { "device",     1, 0, 'i' },
 
2403
        { 0, 0, 0, 0 }
 
2404
};
 
2405
 
 
2406
int main(int argc, char *argv[])
 
2407
{
 
2408
        int opt, i, dev_id = -1;
 
2409
        bdaddr_t ba;
 
2410
 
 
2411
        while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) {
 
2412
                switch (opt) {
 
2413
                case 'i':
 
2414
                        dev_id = hci_devid(optarg);
 
2415
                        if (dev_id < 0) {
 
2416
                                perror("Invalid device");
 
2417
                                exit(1);
 
2418
                        }
 
2419
                        break;
 
2420
 
 
2421
                case 'h':
 
2422
                default:
 
2423
                        usage();
 
2424
                        exit(0);
 
2425
                }
 
2426
        }
 
2427
 
 
2428
        argc -= optind;
 
2429
        argv += optind;
 
2430
        optind = 0;
 
2431
 
 
2432
        if (argc < 1) {
 
2433
                usage();
 
2434
                exit(0);
 
2435
        }
 
2436
 
 
2437
        if (dev_id != -1 && hci_devba(dev_id, &ba) < 0) {
 
2438
                perror("Device is not available");
 
2439
                exit(1);
 
2440
        }
 
2441
 
 
2442
        for (i = 0; command[i].cmd; i++) {
 
2443
                if (strncmp(command[i].cmd, argv[0], 3))
 
2444
                        continue;
 
2445
                command[i].func(dev_id, argc, argv);
 
2446
                break;
 
2447
        }
 
2448
        return 0;
 
2449
}