~ubuntu-branches/ubuntu/wily/bluez/wily

« back to all changes in this revision

Viewing changes to compat/hidd.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) 2003-2008  Marcel Holtmann <marcel@holtmann.org>
 
6
 *
 
7
 *
 
8
 *  This program is free software; you can redistribute it and/or modify
 
9
 *  it under the terms of the GNU General Public License as published by
 
10
 *  the Free Software Foundation; either version 2 of the License, or
 
11
 *  (at your option) any later version.
 
12
 *
 
13
 *  This program is distributed in the hope that it will be useful,
 
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
 *  GNU General Public License for more details.
 
17
 *
 
18
 *  You should have received a copy of the GNU General Public License
 
19
 *  along with this program; if not, write to the Free Software
 
20
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
21
 *
 
22
 */
 
23
 
 
24
#ifdef HAVE_CONFIG_H
 
25
#include <config.h>
 
26
#endif
 
27
 
 
28
#define _GNU_SOURCE
 
29
#include <stdio.h>
 
30
#include <errno.h>
 
31
#include <fcntl.h>
 
32
#include <unistd.h>
 
33
#include <stdlib.h>
 
34
#include <string.h>
 
35
#include <syslog.h>
 
36
#include <signal.h>
 
37
#include <getopt.h>
 
38
#include <sys/poll.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
#include <bluetooth/l2cap.h>
 
46
#include <bluetooth/sdp.h>
 
47
#include <bluetooth/hidp.h>
 
48
 
 
49
#include "sdp.h"
 
50
#include "hidd.h"
 
51
 
 
52
#ifdef NEED_PPOLL
 
53
#include "ppoll.h"
 
54
#endif
 
55
 
 
56
enum {
 
57
        NONE,
 
58
        SHOW,
 
59
        SERVER,
 
60
        SEARCH,
 
61
        CONNECT,
 
62
        KILL
 
63
};
 
64
 
 
65
static volatile sig_atomic_t __io_canceled = 0;
 
66
 
 
67
static void sig_hup(int sig)
 
68
{
 
69
}
 
70
 
 
71
static void sig_term(int sig)
 
72
{
 
73
        __io_canceled = 1;
 
74
}
 
75
 
 
76
static int l2cap_connect(bdaddr_t *src, bdaddr_t *dst, unsigned short psm)
 
77
{
 
78
        struct sockaddr_l2 addr;
 
79
        struct l2cap_options opts;
 
80
        int sk;
 
81
 
 
82
        if ((sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0)
 
83
                return -1;
 
84
 
 
85
        memset(&addr, 0, sizeof(addr));
 
86
        addr.l2_family  = AF_BLUETOOTH;
 
87
        bacpy(&addr.l2_bdaddr, src);
 
88
 
 
89
        if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
 
90
                close(sk);
 
91
                return -1;
 
92
        }
 
93
 
 
94
        memset(&opts, 0, sizeof(opts));
 
95
        opts.imtu = HIDP_DEFAULT_MTU;
 
96
        opts.omtu = HIDP_DEFAULT_MTU;
 
97
        opts.flush_to = 0xffff;
 
98
 
 
99
        setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts));
 
100
 
 
101
        memset(&addr, 0, sizeof(addr));
 
102
        addr.l2_family  = AF_BLUETOOTH;
 
103
        bacpy(&addr.l2_bdaddr, dst);
 
104
        addr.l2_psm = htobs(psm);
 
105
 
 
106
        if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
 
107
                close(sk);
 
108
                return -1;
 
109
        }
 
110
 
 
111
        return sk;
 
112
}
 
113
 
 
114
static int l2cap_listen(const bdaddr_t *bdaddr, unsigned short psm, int lm, int backlog)
 
115
{
 
116
        struct sockaddr_l2 addr;
 
117
        struct l2cap_options opts;
 
118
        int sk;
 
119
 
 
120
        if ((sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0)
 
121
                return -1;
 
122
 
 
123
        memset(&addr, 0, sizeof(addr));
 
124
        addr.l2_family = AF_BLUETOOTH;
 
125
        bacpy(&addr.l2_bdaddr, bdaddr);
 
126
        addr.l2_psm = htobs(psm);
 
127
 
 
128
        if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
 
129
                close(sk);
 
130
                return -1;
 
131
        }
 
132
 
 
133
        setsockopt(sk, SOL_L2CAP, L2CAP_LM, &lm, sizeof(lm));
 
134
 
 
135
        memset(&opts, 0, sizeof(opts));
 
136
        opts.imtu = HIDP_DEFAULT_MTU;
 
137
        opts.omtu = HIDP_DEFAULT_MTU;
 
138
        opts.flush_to = 0xffff;
 
139
 
 
140
        setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts));
 
141
 
 
142
        if (listen(sk, backlog) < 0) {
 
143
                close(sk);
 
144
                return -1;
 
145
        }
 
146
 
 
147
        return sk;
 
148
}
 
149
 
 
150
static int l2cap_accept(int sk, bdaddr_t *bdaddr)
 
151
{
 
152
        struct sockaddr_l2 addr;
 
153
        socklen_t addrlen;
 
154
        int nsk;
 
155
 
 
156
        memset(&addr, 0, sizeof(addr));
 
157
        addrlen = sizeof(addr);
 
158
 
 
159
        if ((nsk = accept(sk, (struct sockaddr *) &addr, &addrlen)) < 0)
 
160
                return -1;
 
161
 
 
162
        if (bdaddr)
 
163
                bacpy(bdaddr, &addr.l2_bdaddr);
 
164
 
 
165
        return nsk;
 
166
}
 
167
 
 
168
static int request_authentication(bdaddr_t *src, bdaddr_t *dst)
 
169
{
 
170
        struct hci_conn_info_req *cr;
 
171
        char addr[18];
 
172
        int err, dd, dev_id;
 
173
 
 
174
        ba2str(src, addr);
 
175
        dev_id = hci_devid(addr);
 
176
        if (dev_id < 0)
 
177
                return dev_id;
 
178
 
 
179
        dd = hci_open_dev(dev_id);
 
180
        if (dd < 0)
 
181
                return dd;
 
182
 
 
183
        cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
 
184
        if (!cr)
 
185
                return -ENOMEM;
 
186
 
 
187
        bacpy(&cr->bdaddr, dst);
 
188
        cr->type = ACL_LINK;
 
189
        err = ioctl(dd, HCIGETCONNINFO, (unsigned long) cr);
 
190
        if (err < 0) {
 
191
                free(cr);
 
192
                hci_close_dev(dd);
 
193
                return err;
 
194
        }
 
195
 
 
196
        err = hci_authenticate_link(dd, htobs(cr->conn_info->handle), 25000);
 
197
 
 
198
        free(cr);
 
199
        hci_close_dev(dd);
 
200
 
 
201
        return err;
 
202
}
 
203
 
 
204
static int request_encryption(bdaddr_t *src, bdaddr_t *dst)
 
205
{
 
206
        struct hci_conn_info_req *cr;
 
207
        char addr[18];
 
208
        int err, dd, dev_id;
 
209
 
 
210
        ba2str(src, addr);
 
211
        dev_id = hci_devid(addr);
 
212
        if (dev_id < 0)
 
213
                return dev_id;
 
214
 
 
215
        dd = hci_open_dev(dev_id);
 
216
        if (dd < 0)
 
217
                return dd;
 
218
 
 
219
        cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
 
220
        if (!cr)
 
221
                return -ENOMEM;
 
222
 
 
223
        bacpy(&cr->bdaddr, dst);
 
224
        cr->type = ACL_LINK;
 
225
        err = ioctl(dd, HCIGETCONNINFO, (unsigned long) cr);
 
226
        if (err < 0) {
 
227
                free(cr);
 
228
                hci_close_dev(dd);
 
229
                return err;
 
230
        }
 
231
 
 
232
        err = hci_encrypt_link(dd, htobs(cr->conn_info->handle), 1, 25000);
 
233
 
 
234
        free(cr);
 
235
        hci_close_dev(dd);
 
236
 
 
237
        return err;
 
238
}
 
239
 
 
240
static void enable_sixaxis(int csk)
 
241
{
 
242
        const unsigned char buf[] = {
 
243
                0x53 /*HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE*/,
 
244
                0xf4,  0x42, 0x03, 0x00, 0x00 };
 
245
        int err;
 
246
 
 
247
        err = write(csk, buf, sizeof(buf));
 
248
}
 
249
 
 
250
static int create_device(int ctl, int csk, int isk, uint8_t subclass, int nosdp, int nocheck, int bootonly, int encrypt, int timeout)
 
251
{
 
252
        struct hidp_connadd_req req;
 
253
        struct sockaddr_l2 addr;
 
254
        socklen_t addrlen;
 
255
        bdaddr_t src, dst;
 
256
        char bda[18];
 
257
        int err;
 
258
 
 
259
        memset(&addr, 0, sizeof(addr));
 
260
        addrlen = sizeof(addr);
 
261
 
 
262
        if (getsockname(csk, (struct sockaddr *) &addr, &addrlen) < 0)
 
263
                return -1;
 
264
 
 
265
        bacpy(&src, &addr.l2_bdaddr);
 
266
 
 
267
        memset(&addr, 0, sizeof(addr));
 
268
        addrlen = sizeof(addr);
 
269
 
 
270
        if (getpeername(csk, (struct sockaddr *) &addr, &addrlen) < 0)
 
271
                return -1;
 
272
 
 
273
        bacpy(&dst, &addr.l2_bdaddr);
 
274
 
 
275
        memset(&req, 0, sizeof(req));
 
276
        req.ctrl_sock = csk;
 
277
        req.intr_sock = isk;
 
278
        req.flags     = 0;
 
279
        req.idle_to   = timeout * 60;
 
280
 
 
281
        err = get_stored_device_info(&src, &dst, &req);
 
282
        if (!err)
 
283
                goto create;
 
284
 
 
285
        if (!nocheck) {
 
286
                ba2str(&dst, bda);
 
287
                syslog(LOG_ERR, "Rejected connection from unknown device %s", bda);
 
288
                /* Return no error to avoid run_server() complaining too */
 
289
                return 0;
 
290
        }
 
291
 
 
292
        if (!nosdp) {
 
293
                err = get_sdp_device_info(&src, &dst, &req);
 
294
                if (err < 0)
 
295
                        goto error;
 
296
        } else {
 
297
                struct l2cap_conninfo conn;
 
298
                socklen_t size;
 
299
                uint8_t class[3];
 
300
 
 
301
                memset(&conn, 0, sizeof(conn));
 
302
                size = sizeof(conn);
 
303
                if (getsockopt(csk, SOL_L2CAP, L2CAP_CONNINFO, &conn, &size) < 0)
 
304
                        memset(class, 0, 3);
 
305
                else
 
306
                        memcpy(class, conn.dev_class, 3);
 
307
 
 
308
                if (class[1] == 0x25 && (class[2] == 0x00 || class[2] == 0x01))
 
309
                        req.subclass = class[0];
 
310
                else
 
311
                        req.subclass = 0xc0;
 
312
        }
 
313
 
 
314
create:
 
315
        if (subclass != 0x00)
 
316
                req.subclass = subclass;
 
317
 
 
318
        ba2str(&dst, bda);
 
319
        syslog(LOG_INFO, "New HID device %s (%s)", bda, req.name);
 
320
 
 
321
        if (encrypt && (req.subclass & 0x40)) {
 
322
                err = request_authentication(&src, &dst);
 
323
                if (err < 0) {
 
324
                        syslog(LOG_ERR, "Authentication for %s failed", bda);
 
325
                        goto error;
 
326
                }
 
327
 
 
328
                err = request_encryption(&src, &dst);
 
329
                if (err < 0)
 
330
                        syslog(LOG_ERR, "Encryption for %s failed", bda);
 
331
        }
 
332
 
 
333
        if (bootonly) {
 
334
                req.rd_size = 0;
 
335
                req.flags |= (1 << HIDP_BOOT_PROTOCOL_MODE);
 
336
        }
 
337
 
 
338
        if (req.vendor == 0x054c && req.product == 0x0268)
 
339
                enable_sixaxis(csk);
 
340
 
 
341
        err = ioctl(ctl, HIDPCONNADD, &req);
 
342
 
 
343
error:
 
344
        if (req.rd_data)
 
345
                free(req.rd_data);
 
346
 
 
347
        return err;
 
348
}
 
349
 
 
350
static void run_server(int ctl, int csk, int isk, uint8_t subclass, int nosdp, int nocheck, int bootonly, int encrypt, int timeout)
 
351
{
 
352
        struct pollfd p[2];
 
353
        sigset_t sigs;
 
354
        short events;
 
355
        int err, ncsk, nisk;
 
356
 
 
357
        sigfillset(&sigs);
 
358
        sigdelset(&sigs, SIGCHLD);
 
359
        sigdelset(&sigs, SIGPIPE);
 
360
        sigdelset(&sigs, SIGTERM);
 
361
        sigdelset(&sigs, SIGINT);
 
362
        sigdelset(&sigs, SIGHUP);
 
363
 
 
364
        p[0].fd = csk;
 
365
        p[0].events = POLLIN | POLLERR | POLLHUP;
 
366
 
 
367
        p[1].fd = isk;
 
368
        p[1].events = POLLIN | POLLERR | POLLHUP;
 
369
 
 
370
        while (!__io_canceled) {
 
371
                p[0].revents = 0;
 
372
                p[1].revents = 0;
 
373
 
 
374
                if (ppoll(p, 2, NULL, &sigs) < 1)
 
375
                        continue;
 
376
 
 
377
                events = p[0].revents | p[1].revents;
 
378
 
 
379
                if (events & POLLIN) {
 
380
                        ncsk = l2cap_accept(csk, NULL);
 
381
                        nisk = l2cap_accept(isk, NULL);
 
382
 
 
383
                        err = create_device(ctl, ncsk, nisk, subclass, nosdp, nocheck, bootonly, encrypt, timeout);
 
384
                        if (err < 0)
 
385
                                syslog(LOG_ERR, "HID create error %d (%s)",
 
386
                                                errno, strerror(errno));
 
387
 
 
388
                        close(nisk);
 
389
                        sleep(1);
 
390
                        close(ncsk);
 
391
                }
 
392
        }
 
393
}
 
394
 
 
395
static char *hidp_state[] = {
 
396
        "unknown",
 
397
        "connected",
 
398
        "open",
 
399
        "bound",
 
400
        "listening",
 
401
        "connecting",
 
402
        "connecting",
 
403
        "config",
 
404
        "disconnecting",
 
405
        "closed"
 
406
};
 
407
 
 
408
static char *hidp_flagstostr(uint32_t flags)
 
409
{
 
410
        static char str[100];
 
411
        str[0] = 0;
 
412
 
 
413
        strcat(str, "[");
 
414
 
 
415
        if (flags & (1 << HIDP_BOOT_PROTOCOL_MODE))
 
416
                strcat(str, "boot-protocol");
 
417
 
 
418
        strcat(str, "]");
 
419
 
 
420
        return str;
 
421
}
 
422
 
 
423
static void do_show(int ctl)
 
424
{
 
425
        struct hidp_connlist_req req;
 
426
        struct hidp_conninfo ci[16];
 
427
        char addr[18];
 
428
        int i;
 
429
 
 
430
        req.cnum = 16;
 
431
        req.ci   = ci;
 
432
 
 
433
        if (ioctl(ctl, HIDPGETCONNLIST, &req) < 0) {
 
434
                perror("Can't get connection list");
 
435
                close(ctl);
 
436
                exit(1);
 
437
        }
 
438
 
 
439
        for (i = 0; i < req.cnum; i++) {
 
440
                ba2str(&ci[i].bdaddr, addr);
 
441
                printf("%s %s [%04x:%04x] %s %s\n", addr, ci[i].name,
 
442
                        ci[i].vendor, ci[i].product, hidp_state[ci[i].state],
 
443
                        ci[i].flags ? hidp_flagstostr(ci[i].flags) : "");
 
444
        }
 
445
}
 
446
 
 
447
static void do_connect(int ctl, bdaddr_t *src, bdaddr_t *dst, uint8_t subclass, int fakehid, int bootonly, int encrypt, int timeout)
 
448
{
 
449
        struct hidp_connadd_req req;
 
450
        uint16_t uuid = HID_SVCLASS_ID;
 
451
        uint8_t channel = 0;
 
452
        char name[256];
 
453
        int csk, isk, err;
 
454
 
 
455
        memset(&req, 0, sizeof(req));
 
456
 
 
457
        err = get_sdp_device_info(src, dst, &req);
 
458
        if (err < 0 && fakehid)
 
459
                err = get_alternate_device_info(src, dst,
 
460
                                &uuid, &channel, name, sizeof(name) - 1);
 
461
 
 
462
        if (err < 0) {
 
463
                perror("Can't get device information");
 
464
                close(ctl);
 
465
                exit(1);
 
466
        }
 
467
 
 
468
        switch (uuid) {
 
469
        case HID_SVCLASS_ID:
 
470
                goto connect;
 
471
 
 
472
        case SERIAL_PORT_SVCLASS_ID:
 
473
                if (subclass == 0x40 || !strcmp(name, "Cable Replacement")) {
 
474
                        if (epox_presenter(src, dst, channel) < 0) {
 
475
                                close(ctl);
 
476
                                exit(1);
 
477
                        }
 
478
                        break;
 
479
                }
 
480
                if (subclass == 0x1f || !strcmp(name, "SPP slave")) {
 
481
                        if (jthree_keyboard(src, dst, channel) < 0) {
 
482
                                close(ctl);
 
483
                                exit(1);
 
484
                        }
 
485
                        break;
 
486
                }
 
487
                if (subclass == 0x02 || !strcmp(name, "Serial Port")) {
 
488
                        if (celluon_keyboard(src, dst, channel) < 0) {
 
489
                                close(ctl);
 
490
                                exit(1);
 
491
                        }
 
492
                        break;
 
493
                }
 
494
                break;
 
495
 
 
496
        case HEADSET_SVCLASS_ID:
 
497
        case HANDSFREE_SVCLASS_ID:
 
498
                if (headset_presenter(src, dst, channel) < 0) {
 
499
                        close(ctl);
 
500
                        exit(1);
 
501
                }
 
502
                break;
 
503
        }
 
504
 
 
505
        return;
 
506
 
 
507
connect:
 
508
        csk = l2cap_connect(src, dst, L2CAP_PSM_HIDP_CTRL);
 
509
        if (csk < 0) {
 
510
                perror("Can't create HID control channel");
 
511
                close(ctl);
 
512
                exit(1);
 
513
        }
 
514
 
 
515
        isk = l2cap_connect(src, dst, L2CAP_PSM_HIDP_INTR);
 
516
        if (isk < 0) {
 
517
                perror("Can't create HID interrupt channel");
 
518
                close(csk);
 
519
                close(ctl);
 
520
                exit(1);
 
521
        }
 
522
 
 
523
        err = create_device(ctl, csk, isk, subclass, 1, 1, bootonly, encrypt, timeout);
 
524
        if (err < 0) {
 
525
                fprintf(stderr, "HID create error %d (%s)\n",
 
526
                                                errno, strerror(errno));
 
527
                close(isk);
 
528
                sleep(1);
 
529
                close(csk);
 
530
                close(ctl);
 
531
                exit(1);
 
532
        }
 
533
}
 
534
 
 
535
static void do_search(int ctl, bdaddr_t *bdaddr, uint8_t subclass, int fakehid, int bootonly, int encrypt, int timeout)
 
536
{
 
537
        inquiry_info *info = NULL;
 
538
        bdaddr_t src, dst;
 
539
        int i, dev_id, num_rsp, length, flags;
 
540
        char addr[18];
 
541
        uint8_t class[3];
 
542
 
 
543
        ba2str(bdaddr, addr);
 
544
        dev_id = hci_devid(addr);
 
545
        if (dev_id < 0) {
 
546
                dev_id = hci_get_route(NULL);
 
547
                hci_devba(dev_id, &src);
 
548
        } else
 
549
                bacpy(&src, bdaddr);
 
550
 
 
551
        length  = 8;    /* ~10 seconds */
 
552
        num_rsp = 0;
 
553
        flags   = IREQ_CACHE_FLUSH;
 
554
 
 
555
        printf("Searching ...\n");
 
556
 
 
557
        num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags);
 
558
 
 
559
        for (i = 0; i < num_rsp; i++) {
 
560
                memcpy(class, (info+i)->dev_class, 3);
 
561
                if (class[1] == 0x25 && (class[2] == 0x00 || class[2] == 0x01)) {
 
562
                        bacpy(&dst, &(info+i)->bdaddr);
 
563
                        ba2str(&dst, addr);
 
564
 
 
565
                        printf("\tConnecting to device %s\n", addr);
 
566
                        do_connect(ctl, &src, &dst, subclass, fakehid, bootonly, encrypt, timeout);
 
567
                }
 
568
        }
 
569
 
 
570
        if (!fakehid)
 
571
                goto done;
 
572
 
 
573
        for (i = 0; i < num_rsp; i++) {
 
574
                memcpy(class, (info+i)->dev_class, 3);
 
575
                if ((class[0] == 0x00 && class[2] == 0x00 && 
 
576
                                (class[1] == 0x40 || class[1] == 0x1f)) ||
 
577
                                (class[0] == 0x10 && class[1] == 0x02 && class[2] == 0x40)) {
 
578
                        bacpy(&dst, &(info+i)->bdaddr);
 
579
                        ba2str(&dst, addr);
 
580
 
 
581
                        printf("\tConnecting to device %s\n", addr);
 
582
                        do_connect(ctl, &src, &dst, subclass, 1, bootonly, 0, timeout);
 
583
                }
 
584
        }
 
585
 
 
586
done:
 
587
        bt_free(info);
 
588
 
 
589
        if (!num_rsp) {
 
590
                fprintf(stderr, "\tNo devices in range or visible\n");
 
591
                close(ctl);
 
592
                exit(1);
 
593
        }
 
594
}
 
595
 
 
596
static void do_kill(int ctl, bdaddr_t *bdaddr, uint32_t flags)
 
597
{
 
598
        struct hidp_conndel_req req;
 
599
        struct hidp_connlist_req cl;
 
600
        struct hidp_conninfo ci[16];
 
601
        int i;
 
602
 
 
603
        if (!bacmp(bdaddr, BDADDR_ALL)) {
 
604
                cl.cnum = 16;
 
605
                cl.ci   = ci;
 
606
 
 
607
                if (ioctl(ctl, HIDPGETCONNLIST, &cl) < 0) {
 
608
                        perror("Can't get connection list");
 
609
                        close(ctl);
 
610
                        exit(1);
 
611
                }
 
612
 
 
613
                for (i = 0; i < cl.cnum; i++) {
 
614
                        bacpy(&req.bdaddr, &ci[i].bdaddr);
 
615
                        req.flags = flags;
 
616
 
 
617
                        if (ioctl(ctl, HIDPCONNDEL, &req) < 0) {
 
618
                                perror("Can't release connection");
 
619
                                close(ctl);
 
620
                                exit(1);
 
621
                        }
 
622
                }
 
623
 
 
624
        } else {
 
625
                bacpy(&req.bdaddr, bdaddr);
 
626
                req.flags = flags;
 
627
 
 
628
                if (ioctl(ctl, HIDPCONNDEL, &req) < 0) {
 
629
                        perror("Can't release connection");
 
630
                        close(ctl);
 
631
                        exit(1);
 
632
                }
 
633
        }
 
634
}
 
635
 
 
636
static void usage(void)
 
637
{
 
638
        printf("hidd - Bluetooth HID daemon version %s\n\n", VERSION);
 
639
 
 
640
        printf("Usage:\n"
 
641
                "\thidd [options] [commands]\n"
 
642
                "\n");
 
643
 
 
644
        printf("Options:\n"
 
645
                "\t-i <hciX|bdaddr>     Local HCI device or BD Address\n"
 
646
                "\t-t <timeout>         Set idle timeout (in minutes)\n"
 
647
                "\t-b <subclass>        Overwrite the boot mode subclass\n"
 
648
                "\t-n, --nodaemon       Don't fork daemon to background\n"
 
649
                "\t-h, --help           Display help\n"
 
650
                "\n");
 
651
 
 
652
        printf("Commands:\n"
 
653
                "\t--server             Start HID server\n"
 
654
                "\t--search             Search for HID devices\n"
 
655
                "\t--connect <bdaddr>   Connect remote HID device\n"
 
656
                "\t--unplug <bdaddr>    Unplug the HID connection\n"
 
657
                "\t--kill <bdaddr>      Terminate HID connection\n"
 
658
                "\t--killall            Terminate all connections\n"
 
659
                "\t--show               List current HID connections\n"
 
660
                "\n");
 
661
}
 
662
 
 
663
static struct option main_options[] = {
 
664
        { "help",       0, 0, 'h' },
 
665
        { "nodaemon",   0, 0, 'n' },
 
666
        { "subclass",   1, 0, 'b' },
 
667
        { "timeout",    1, 0, 't' },
 
668
        { "device",     1, 0, 'i' },
 
669
        { "master",     0, 0, 'M' },
 
670
        { "encrypt",    0, 0, 'E' },
 
671
        { "nosdp",      0, 0, 'D' },
 
672
        { "nocheck",    0, 0, 'Z' },
 
673
        { "bootonly",   0, 0, 'B' },
 
674
        { "hidonly",    0, 0, 'H' },
 
675
        { "show",       0, 0, 'l' },
 
676
        { "list",       0, 0, 'l' },
 
677
        { "server",     0, 0, 'd' },
 
678
        { "listen",     0, 0, 'd' },
 
679
        { "search",     0, 0, 's' },
 
680
        { "create",     1, 0, 'c' },
 
681
        { "connect",    1, 0, 'c' },
 
682
        { "disconnect", 1, 0, 'k' },
 
683
        { "terminate",  1, 0, 'k' },
 
684
        { "release",    1, 0, 'k' },
 
685
        { "kill",       1, 0, 'k' },
 
686
        { "killall",    0, 0, 'K' },
 
687
        { "unplug",     1, 0, 'u' },
 
688
        { 0, 0, 0, 0 }
 
689
};
 
690
 
 
691
int main(int argc, char *argv[])
 
692
{
 
693
        struct sigaction sa;
 
694
        bdaddr_t bdaddr, dev;
 
695
        uint32_t flags = 0;
 
696
        uint8_t subclass = 0x00;
 
697
        char addr[18];
 
698
        int log_option = LOG_NDELAY | LOG_PID;
 
699
        int opt, ctl, csk, isk;
 
700
        int mode = SHOW, detach = 1, nosdp = 0, nocheck = 0, bootonly = 0;
 
701
        int fakehid = 1, encrypt = 0, timeout = 30, lm = 0;
 
702
 
 
703
        bacpy(&bdaddr, BDADDR_ANY);
 
704
 
 
705
        while ((opt = getopt_long(argc, argv, "+i:nt:b:MEDZBHldsc:k:Ku:h", main_options, NULL)) != -1) {
 
706
                switch(opt) {
 
707
                case 'i':
 
708
                        if (!strncasecmp(optarg, "hci", 3))
 
709
                                hci_devba(atoi(optarg + 3), &bdaddr);
 
710
                        else
 
711
                                str2ba(optarg, &bdaddr);
 
712
                        break;
 
713
                case 'n':
 
714
                        detach = 0;
 
715
                        break;
 
716
                case 't':
 
717
                        timeout = atoi(optarg);
 
718
                        break;
 
719
                case 'b':
 
720
                        if (!strncasecmp(optarg, "0x", 2))
 
721
                                subclass = (uint8_t) strtol(optarg, NULL, 16);
 
722
                        else
 
723
                                subclass = atoi(optarg);
 
724
                        break;
 
725
                case 'M':
 
726
                        lm |= L2CAP_LM_MASTER;
 
727
                        break;
 
728
                case 'E':
 
729
                        encrypt = 1;
 
730
                        break;
 
731
                case 'D':
 
732
                        nosdp = 1;
 
733
                        break;
 
734
                case 'Z':
 
735
                        nocheck = 1;
 
736
                        break;
 
737
                case 'B':
 
738
                        bootonly = 1;
 
739
                        break;
 
740
                case 'H':
 
741
                        fakehid = 0;
 
742
                        break;
 
743
                case 'l':
 
744
                        mode = SHOW;
 
745
                        break;
 
746
                case 'd':
 
747
                        mode = SERVER;
 
748
                        break;
 
749
                case 's':
 
750
                        mode = SEARCH;
 
751
                        break;
 
752
                case 'c':
 
753
                        str2ba(optarg, &dev);
 
754
                        mode = CONNECT;
 
755
                        break;
 
756
                case 'k':
 
757
                        str2ba(optarg, &dev);
 
758
                        mode = KILL;
 
759
                        break;
 
760
                case 'K':
 
761
                        bacpy(&dev, BDADDR_ALL);
 
762
                        mode = KILL;
 
763
                        break;
 
764
                case 'u':
 
765
                        str2ba(optarg, &dev);
 
766
                        flags = (1 << HIDP_VIRTUAL_CABLE_UNPLUG);
 
767
                        mode = KILL;
 
768
                        break;
 
769
                case 'h':
 
770
                        usage();
 
771
                        exit(0);
 
772
                default:
 
773
                        exit(0);
 
774
                }
 
775
        }
 
776
 
 
777
        ba2str(&bdaddr, addr);
 
778
 
 
779
        ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HIDP);
 
780
        if (ctl < 0) {
 
781
                perror("Can't open HIDP control socket");
 
782
                exit(1);
 
783
        }
 
784
 
 
785
        switch (mode) {
 
786
        case SERVER:
 
787
                csk = l2cap_listen(&bdaddr, L2CAP_PSM_HIDP_CTRL, lm, 10);
 
788
                if (csk < 0) {
 
789
                        perror("Can't listen on HID control channel");
 
790
                        close(ctl);
 
791
                        exit(1);
 
792
                }
 
793
 
 
794
                isk = l2cap_listen(&bdaddr, L2CAP_PSM_HIDP_INTR, lm, 10);
 
795
                if (isk < 0) {
 
796
                        perror("Can't listen on HID interrupt channel");
 
797
                        close(ctl);
 
798
                        close(csk);
 
799
                        exit(1);
 
800
                }
 
801
                break;
 
802
 
 
803
        case SEARCH:
 
804
                do_search(ctl, &bdaddr, subclass, fakehid, bootonly, encrypt, timeout);
 
805
                close(ctl);
 
806
                exit(0);
 
807
 
 
808
        case CONNECT:
 
809
                do_connect(ctl, &bdaddr, &dev, subclass, fakehid, bootonly, encrypt, timeout);
 
810
                close(ctl);
 
811
                exit(0);
 
812
 
 
813
        case KILL:
 
814
                do_kill(ctl, &dev, flags);
 
815
                close(ctl);
 
816
                exit(0);
 
817
 
 
818
        default:
 
819
                do_show(ctl);
 
820
                close(ctl);
 
821
                exit(0);
 
822
        }
 
823
 
 
824
        if (detach) {
 
825
                if (daemon(0, 0)) {
 
826
                        perror("Can't start daemon");
 
827
                        exit(1);
 
828
                }
 
829
        } else
 
830
                log_option |= LOG_PERROR;
 
831
 
 
832
        openlog("hidd", log_option, LOG_DAEMON);
 
833
 
 
834
        if (bacmp(&bdaddr, BDADDR_ANY))
 
835
                syslog(LOG_INFO, "Bluetooth HID daemon (%s)", addr);
 
836
        else
 
837
                syslog(LOG_INFO, "Bluetooth HID daemon");
 
838
 
 
839
        memset(&sa, 0, sizeof(sa));
 
840
        sa.sa_flags = SA_NOCLDSTOP;
 
841
 
 
842
        sa.sa_handler = sig_term;
 
843
        sigaction(SIGTERM, &sa, NULL);
 
844
        sigaction(SIGINT,  &sa, NULL);
 
845
        sa.sa_handler = sig_hup;
 
846
        sigaction(SIGHUP, &sa, NULL);
 
847
 
 
848
        sa.sa_handler = SIG_IGN;
 
849
        sigaction(SIGCHLD, &sa, NULL);
 
850
        sigaction(SIGPIPE, &sa, NULL);
 
851
 
 
852
        run_server(ctl, csk, isk, subclass, nosdp, nocheck, bootonly, encrypt, timeout);
 
853
 
 
854
        syslog(LOG_INFO, "Exit");
 
855
 
 
856
        close(csk);
 
857
        close(isk);
 
858
        close(ctl);
 
859
 
 
860
        return 0;
 
861
}