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

« back to all changes in this revision

Viewing changes to compat/fakehid.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 <signal.h>
 
35
#include <sys/poll.h>
 
36
#include <sys/ioctl.h>
 
37
#include <sys/socket.h>
 
38
 
 
39
#include <bluetooth/bluetooth.h>
 
40
#include <bluetooth/rfcomm.h>
 
41
#include <bluetooth/hidp.h>
 
42
 
 
43
#include "hidd.h"
 
44
#include "uinput.h"
 
45
 
 
46
#include <math.h>
 
47
 
 
48
#ifdef NEED_PPOLL
 
49
#include "ppoll.h"
 
50
#endif
 
51
 
 
52
static volatile sig_atomic_t __io_canceled = 0;
 
53
 
 
54
static void sig_hup(int sig)
 
55
{
 
56
}
 
57
 
 
58
static void sig_term(int sig)
 
59
{
 
60
        __io_canceled = 1;
 
61
}
 
62
 
 
63
static void send_event(int fd, uint16_t type, uint16_t code, int32_t value)
 
64
{
 
65
        struct uinput_event event;
 
66
        int len;
 
67
 
 
68
        if (fd <= fileno(stderr))
 
69
                return;
 
70
 
 
71
        memset(&event, 0, sizeof(event));
 
72
        event.type = type;
 
73
        event.code = code;
 
74
        event.value = value;
 
75
 
 
76
        len = write(fd, &event, sizeof(event));
 
77
}
 
78
 
 
79
static int uinput_create(char *name, int keyboard, int mouse)
 
80
{
 
81
        struct uinput_dev dev;
 
82
        int fd, aux;
 
83
 
 
84
        fd = open("/dev/uinput", O_RDWR);
 
85
        if (fd < 0) {
 
86
                fd = open("/dev/input/uinput", O_RDWR);
 
87
                if (fd < 0) {
 
88
                        fd = open("/dev/misc/uinput", O_RDWR);
 
89
                        if (fd < 0) {
 
90
                                fprintf(stderr, "Can't open input device: %s (%d)\n",
 
91
                                                        strerror(errno), errno);
 
92
                                return -1;
 
93
                        }
 
94
                }
 
95
        }
 
96
 
 
97
        memset(&dev, 0, sizeof(dev));
 
98
 
 
99
        if (name)
 
100
                strncpy(dev.name, name, UINPUT_MAX_NAME_SIZE);
 
101
 
 
102
        dev.id.bustype = BUS_BLUETOOTH;
 
103
        dev.id.vendor  = 0x0000;
 
104
        dev.id.product = 0x0000;
 
105
        dev.id.version = 0x0000;
 
106
 
 
107
        if (write(fd, &dev, sizeof(dev)) < 0) {
 
108
                fprintf(stderr, "Can't write device information: %s (%d)\n",
 
109
                                                        strerror(errno), errno);
 
110
                close(fd);
 
111
                return -1;
 
112
        }
 
113
 
 
114
        if (mouse) {
 
115
                ioctl(fd, UI_SET_EVBIT, EV_REL);
 
116
 
 
117
                for (aux = REL_X; aux <= REL_MISC; aux++)
 
118
                        ioctl(fd, UI_SET_RELBIT, aux);
 
119
        }
 
120
 
 
121
        if (keyboard) {
 
122
                ioctl(fd, UI_SET_EVBIT, EV_KEY);
 
123
                ioctl(fd, UI_SET_EVBIT, EV_LED);
 
124
                ioctl(fd, UI_SET_EVBIT, EV_REP);
 
125
 
 
126
                for (aux = KEY_RESERVED; aux <= KEY_UNKNOWN; aux++)
 
127
                        ioctl(fd, UI_SET_KEYBIT, aux);
 
128
 
 
129
                //for (aux = LED_NUML; aux <= LED_MISC; aux++)
 
130
                //      ioctl(fd, UI_SET_LEDBIT, aux);
 
131
        }
 
132
 
 
133
        if (mouse) {
 
134
                ioctl(fd, UI_SET_EVBIT, EV_KEY);
 
135
 
 
136
                for (aux = BTN_LEFT; aux <= BTN_BACK; aux++)
 
137
                        ioctl(fd, UI_SET_KEYBIT, aux);
 
138
        }
 
139
 
 
140
        ioctl(fd, UI_DEV_CREATE);
 
141
 
 
142
        return fd;
 
143
}
 
144
 
 
145
static int rfcomm_connect(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel)
 
146
{
 
147
        struct sockaddr_rc addr;
 
148
        int sk;
 
149
 
 
150
        sk = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
 
151
        if (sk < 0) {
 
152
                fprintf(stderr, "Can't create socket: %s (%d)\n",
 
153
                                                        strerror(errno), errno);
 
154
                return -1;
 
155
        }
 
156
 
 
157
        memset(&addr, 0, sizeof(addr));
 
158
        addr.rc_family = AF_BLUETOOTH;
 
159
        bacpy(&addr.rc_bdaddr, src);
 
160
 
 
161
        if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
 
162
                fprintf(stderr, "Can't bind socket: %s (%d)\n",
 
163
                                                        strerror(errno), errno);
 
164
                close(sk);
 
165
                return -1;
 
166
        }
 
167
 
 
168
        memset(&addr, 0, sizeof(addr));
 
169
        addr.rc_family = AF_BLUETOOTH;
 
170
        bacpy(&addr.rc_bdaddr, dst);
 
171
        addr.rc_channel = channel;
 
172
 
 
173
        if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
 
174
                fprintf(stderr, "Can't connect: %s (%d)\n",
 
175
                                                        strerror(errno), errno);
 
176
                close(sk);
 
177
                return -1;
 
178
        }
 
179
 
 
180
        return sk;
 
181
}
 
182
 
 
183
static void func(int fd)
 
184
{
 
185
}
 
186
 
 
187
static void back(int fd)
 
188
{
 
189
}
 
190
 
 
191
static void next(int fd)
 
192
{
 
193
}
 
194
 
 
195
static void button(int fd, unsigned int button, int is_press)
 
196
{
 
197
        switch (button) {
 
198
        case 1:
 
199
                send_event(fd, EV_KEY, BTN_LEFT, is_press);
 
200
                break;
 
201
        case 3:
 
202
                send_event(fd, EV_KEY, BTN_RIGHT, is_press);
 
203
                break;
 
204
        }
 
205
 
 
206
        send_event(fd, EV_SYN, SYN_REPORT, 0);
 
207
}
 
208
 
 
209
static void move(int fd, unsigned int direction)
 
210
{
 
211
        double angle;
 
212
        int32_t x, y;
 
213
 
 
214
        angle = (direction * 22.5) * 3.1415926 / 180;
 
215
        x = (int) (sin(angle) * 8);
 
216
        y = (int) (cos(angle) * -8);
 
217
 
 
218
        send_event(fd, EV_REL, REL_X, x);
 
219
        send_event(fd, EV_REL, REL_Y, y);
 
220
 
 
221
        send_event(fd, EV_SYN, SYN_REPORT, 0);
 
222
}
 
223
 
 
224
static inline void epox_decode(int fd, unsigned char event)
 
225
{
 
226
        switch (event) {
 
227
        case 48:
 
228
                func(fd); break;
 
229
        case 55:
 
230
                back(fd); break;
 
231
        case 56:
 
232
                next(fd); break;
 
233
        case 53:
 
234
                button(fd, 1, 1); break;
 
235
        case 121:
 
236
                button(fd, 1, 0); break;
 
237
        case 113:
 
238
                break;
 
239
        case 54:
 
240
                button(fd, 3, 1); break;
 
241
        case 120:
 
242
                button(fd, 3, 0); break;
 
243
        case 112:
 
244
                break;
 
245
        case 51:
 
246
                move(fd, 0); break;
 
247
        case 97:
 
248
                move(fd, 1); break;
 
249
        case 65:
 
250
                move(fd, 2); break;
 
251
        case 98:
 
252
                move(fd, 3); break;
 
253
        case 50:
 
254
                move(fd, 4); break;
 
255
        case 99:
 
256
                move(fd, 5); break;
 
257
        case 67:
 
258
                move(fd, 6); break;
 
259
        case 101:
 
260
                move(fd, 7); break;
 
261
        case 52:
 
262
                move(fd, 8); break;
 
263
        case 100:
 
264
                move(fd, 9); break;
 
265
        case 66:
 
266
                move(fd, 10); break;
 
267
        case 102:
 
268
                move(fd, 11); break;
 
269
        case 49:
 
270
                move(fd, 12); break;
 
271
        case 103:
 
272
                move(fd, 13); break;
 
273
        case 57:
 
274
                move(fd, 14); break;
 
275
        case 104:
 
276
                move(fd, 15); break;
 
277
        case 69:
 
278
                break;
 
279
        default:
 
280
                printf("Unknown event code %d\n", event);
 
281
                break;
 
282
        }
 
283
}
 
284
 
 
285
int epox_presenter(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel)
 
286
{
 
287
        unsigned char buf[16];
 
288
        struct sigaction sa;
 
289
        struct pollfd p;
 
290
        sigset_t sigs;
 
291
        char addr[18];
 
292
        int i, fd, sk, len;
 
293
 
 
294
        sk = rfcomm_connect(src, dst, channel);
 
295
        if (sk < 0)
 
296
                return -1;
 
297
 
 
298
        fd = uinput_create("Bluetooth Presenter", 0, 1);
 
299
        if (fd < 0) {
 
300
                close(sk);
 
301
                return -1;
 
302
        }
 
303
 
 
304
        ba2str(dst, addr);
 
305
 
 
306
        printf("Connected to %s on channel %d\n", addr, channel);
 
307
        printf("Press CTRL-C for hangup\n");
 
308
 
 
309
        memset(&sa, 0, sizeof(sa));
 
310
        sa.sa_flags   = SA_NOCLDSTOP;
 
311
        sa.sa_handler = SIG_IGN;
 
312
        sigaction(SIGCHLD, &sa, NULL);
 
313
        sigaction(SIGPIPE, &sa, NULL);
 
314
 
 
315
        sa.sa_handler = sig_term;
 
316
        sigaction(SIGTERM, &sa, NULL);
 
317
        sigaction(SIGINT,  &sa, NULL);
 
318
 
 
319
        sa.sa_handler = sig_hup;
 
320
        sigaction(SIGHUP, &sa, NULL);
 
321
 
 
322
        sigfillset(&sigs);
 
323
        sigdelset(&sigs, SIGCHLD);
 
324
        sigdelset(&sigs, SIGPIPE);
 
325
        sigdelset(&sigs, SIGTERM);
 
326
        sigdelset(&sigs, SIGINT);
 
327
        sigdelset(&sigs, SIGHUP);
 
328
 
 
329
        p.fd = sk;
 
330
        p.events = POLLIN | POLLERR | POLLHUP;
 
331
 
 
332
        while (!__io_canceled) {
 
333
                p.revents = 0;
 
334
                if (ppoll(&p, 1, NULL, &sigs) < 1)
 
335
                        continue;
 
336
 
 
337
                len = read(sk, buf, sizeof(buf));
 
338
                if (len < 0)
 
339
                        break;
 
340
 
 
341
                for (i = 0; i < len; i++)
 
342
                        epox_decode(fd, buf[i]);
 
343
        }
 
344
 
 
345
        printf("Disconnected\n");
 
346
 
 
347
        ioctl(fd, UI_DEV_DESTROY);
 
348
 
 
349
        close(fd);
 
350
        close(sk);
 
351
 
 
352
        return 0;
 
353
}
 
354
 
 
355
int headset_presenter(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel)
 
356
{
 
357
        printf("Not implemented\n");
 
358
        return -1;
 
359
}
 
360
 
 
361
/* The strange meta key close to Ctrl has been assigned to Esc,
 
362
   Fn key to CtrlR and the left space to Alt*/
 
363
 
 
364
static unsigned char jthree_keycodes[63] = {
 
365
        KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6,
 
366
        KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T,
 
367
        KEY_A, KEY_S, KEY_D, KEY_F, KEY_G,
 
368
        KEY_Z, KEY_X, KEY_C, KEY_V, KEY_B,
 
369
        KEY_LEFTALT, KEY_TAB, KEY_CAPSLOCK, KEY_ESC,
 
370
        KEY_7, KEY_8, KEY_9, KEY_0, KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE,
 
371
        KEY_Y, KEY_U, KEY_I, KEY_O, KEY_P, KEY_LEFTBRACE, KEY_RIGHTBRACE,
 
372
        KEY_H, KEY_J, KEY_K, KEY_L, KEY_SEMICOLON, KEY_APOSTROPHE, KEY_ENTER,
 
373
        KEY_N, KEY_M, KEY_COMMA, KEY_DOT, KEY_SLASH, KEY_UP,
 
374
        KEY_SPACE, KEY_COMPOSE, KEY_LEFT, KEY_DOWN, KEY_RIGHT,
 
375
        KEY_LEFTCTRL, KEY_RIGHTSHIFT, KEY_LEFTSHIFT, KEY_DELETE, KEY_RIGHTCTRL, KEY_RIGHTALT,
 
376
};
 
377
 
 
378
static inline void jthree_decode(int fd, unsigned char event)
 
379
{
 
380
        if (event > 63)
 
381
                send_event(fd, EV_KEY, jthree_keycodes[event & 0x3f], 0);
 
382
        else
 
383
                send_event(fd, EV_KEY, jthree_keycodes[event - 1], 1);
 
384
}
 
385
 
 
386
int jthree_keyboard(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel)
 
387
{
 
388
        unsigned char buf[16];
 
389
        struct sigaction sa;
 
390
        struct pollfd p;
 
391
        sigset_t sigs;
 
392
        char addr[18];
 
393
        int i, fd, sk, len;
 
394
 
 
395
        sk = rfcomm_connect(src, dst, channel);
 
396
        if (sk < 0)
 
397
                return -1;
 
398
 
 
399
        fd = uinput_create("J-Three Keyboard", 1, 0);
 
400
        if (fd < 0) {
 
401
                close(sk);
 
402
                return -1;
 
403
        }
 
404
 
 
405
        ba2str(dst, addr);
 
406
 
 
407
        printf("Connected to %s on channel %d\n", addr, channel);
 
408
        printf("Press CTRL-C for hangup\n");
 
409
 
 
410
        memset(&sa, 0, sizeof(sa));
 
411
        sa.sa_flags   = SA_NOCLDSTOP;
 
412
        sa.sa_handler = SIG_IGN;
 
413
        sigaction(SIGCHLD, &sa, NULL);
 
414
        sigaction(SIGPIPE, &sa, NULL);
 
415
 
 
416
        sa.sa_handler = sig_term;
 
417
        sigaction(SIGTERM, &sa, NULL);
 
418
        sigaction(SIGINT,  &sa, NULL);
 
419
 
 
420
        sa.sa_handler = sig_hup;
 
421
        sigaction(SIGHUP, &sa, NULL);
 
422
 
 
423
        sigfillset(&sigs);
 
424
        sigdelset(&sigs, SIGCHLD);
 
425
        sigdelset(&sigs, SIGPIPE);
 
426
        sigdelset(&sigs, SIGTERM);
 
427
        sigdelset(&sigs, SIGINT);
 
428
        sigdelset(&sigs, SIGHUP);
 
429
 
 
430
        p.fd = sk;
 
431
        p.events = POLLIN | POLLERR | POLLHUP;
 
432
 
 
433
        while (!__io_canceled) {
 
434
                p.revents = 0;
 
435
                if (ppoll(&p, 1, NULL, &sigs) < 1)
 
436
                        continue;
 
437
 
 
438
                len = read(sk, buf, sizeof(buf));
 
439
                if (len < 0)
 
440
                        break;
 
441
 
 
442
                for (i = 0; i < len; i++)
 
443
                        jthree_decode(fd, buf[i]);
 
444
        }
 
445
 
 
446
        printf("Disconnected\n");
 
447
 
 
448
        ioctl(fd, UI_DEV_DESTROY);
 
449
 
 
450
        close(fd);
 
451
        close(sk);
 
452
 
 
453
        return 0;
 
454
}
 
455
 
 
456
static const int celluon_xlate_num[10] = {
 
457
        KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9
 
458
};
 
459
 
 
460
static const int celluon_xlate_char[26] = {
 
461
        KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, KEY_H, KEY_I, KEY_J,
 
462
        KEY_K, KEY_L, KEY_M, KEY_N, KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T,
 
463
        KEY_U, KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z
 
464
};
 
465
 
 
466
static int celluon_xlate(int c)
 
467
{
 
468
        if (c >= '0' && c <= '9')
 
469
                return celluon_xlate_num[c - '0'];
 
470
 
 
471
        if (c >= 'A' && c <= 'Z')
 
472
                return celluon_xlate_char[c - 'A'];
 
473
 
 
474
        switch (c) {
 
475
        case 0x08:
 
476
                return KEY_BACKSPACE;
 
477
        case 0x09:
 
478
                return KEY_TAB;
 
479
        case 0x0d:
 
480
                return KEY_ENTER;
 
481
        case 0x11:
 
482
                return KEY_LEFTCTRL;
 
483
        case 0x14:
 
484
                return KEY_CAPSLOCK;
 
485
        case 0x20:
 
486
                return KEY_SPACE;
 
487
        case 0x25:
 
488
                return KEY_LEFT;
 
489
        case 0x26:
 
490
                return KEY_UP;
 
491
        case 0x27:
 
492
                return KEY_RIGHT;
 
493
        case 0x28:
 
494
                return KEY_DOWN;
 
495
        case 0x2e:
 
496
                return KEY_DELETE;
 
497
        case 0x5b:
 
498
                return KEY_MENU;
 
499
        case 0xa1:
 
500
                return KEY_RIGHTSHIFT;
 
501
        case 0xa0:
 
502
                return KEY_LEFTSHIFT;
 
503
        case 0xba:
 
504
                return KEY_SEMICOLON;
 
505
        case 0xbd:
 
506
                return KEY_MINUS;
 
507
        case 0xbc:
 
508
                return KEY_COMMA;
 
509
        case 0xbb:
 
510
                return KEY_EQUAL;
 
511
        case 0xbe:
 
512
                return KEY_DOT;
 
513
        case 0xbf:
 
514
                return KEY_SLASH;
 
515
        case 0xc0:
 
516
                return KEY_GRAVE;
 
517
        case 0xdb:
 
518
                return KEY_LEFTBRACE;
 
519
        case 0xdc:
 
520
                return KEY_BACKSLASH;
 
521
        case 0xdd:
 
522
                return KEY_RIGHTBRACE;
 
523
        case 0xde:
 
524
                return KEY_APOSTROPHE;
 
525
        case 0xff03:
 
526
                return KEY_HOMEPAGE;
 
527
        case 0xff04:
 
528
                return KEY_TIME;
 
529
        case 0xff06:
 
530
                return KEY_OPEN;
 
531
        case 0xff07:
 
532
                return KEY_LIST;
 
533
        case 0xff08:
 
534
                return KEY_MAIL;
 
535
        case 0xff30:
 
536
                return KEY_CALC;
 
537
        case 0xff1a: /* Map FN to ALT */
 
538
                return KEY_LEFTALT;
 
539
        case 0xff2f:
 
540
                return KEY_INFO;
 
541
        default:
 
542
                printf("Unknown key %x\n", c);
 
543
                return c;
 
544
        }
 
545
}
 
546
 
 
547
struct celluon_state {
 
548
        int len;        /* Expected length of current packet */
 
549
        int count;      /* Number of bytes received */
 
550
        int action;
 
551
        int key;
 
552
};
 
553
 
 
554
static void celluon_decode(int fd, struct celluon_state *s, uint8_t c)
 
555
{
 
556
        if (s->count < 2 && c != 0xa5) {
 
557
                /* Lost Sync */
 
558
                s->count = 0;
 
559
                return;
 
560
        }
 
561
 
 
562
        switch (s->count) {
 
563
        case 0:
 
564
                /* New packet - Reset state */
 
565
                s->len = 30;
 
566
                s->key = 0;
 
567
                break;
 
568
        case 1:
 
569
                break;
 
570
        case 6:
 
571
                s->action = c;
 
572
                break;
 
573
        case 28:
 
574
                s->key = c;
 
575
                if (c == 0xff)
 
576
                        s->len = 31;
 
577
                break;
 
578
        case 29:
 
579
        case 30:
 
580
                if (s->count == s->len - 1) {
 
581
                        /* TODO: Verify checksum */
 
582
                        if (s->action < 2) {
 
583
                                send_event(fd, EV_KEY, celluon_xlate(s->key),
 
584
                                                                s->action);
 
585
                        }
 
586
                        s->count = -1;
 
587
                } else {
 
588
                        s->key = (s->key << 8) | c;
 
589
                }
 
590
                break;
 
591
        }
 
592
 
 
593
        s->count++;
 
594
 
 
595
        return;
 
596
}
 
597
 
 
598
int celluon_keyboard(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel)
 
599
{
 
600
        unsigned char buf[16];
 
601
        struct sigaction sa;
 
602
        struct pollfd p;
 
603
        sigset_t sigs;
 
604
        char addr[18];
 
605
        int i, fd, sk, len;
 
606
        struct celluon_state s;
 
607
 
 
608
        sk = rfcomm_connect(src, dst, channel);
 
609
        if (sk < 0)
 
610
                return -1;
 
611
 
 
612
        fd = uinput_create("Celluon Keyboard", 1, 0);
 
613
        if (fd < 0) {
 
614
                close(sk);
 
615
                return -1;
 
616
        }
 
617
 
 
618
        ba2str(dst, addr);
 
619
 
 
620
        printf("Connected to %s on channel %d\n", addr, channel);
 
621
        printf("Press CTRL-C for hangup\n");
 
622
 
 
623
        memset(&sa, 0, sizeof(sa));
 
624
        sa.sa_flags   = SA_NOCLDSTOP;
 
625
        sa.sa_handler = SIG_IGN;
 
626
        sigaction(SIGCHLD, &sa, NULL);
 
627
        sigaction(SIGPIPE, &sa, NULL);
 
628
 
 
629
        sa.sa_handler = sig_term;
 
630
        sigaction(SIGTERM, &sa, NULL);
 
631
        sigaction(SIGINT,  &sa, NULL);
 
632
 
 
633
        sa.sa_handler = sig_hup;
 
634
        sigaction(SIGHUP, &sa, NULL);
 
635
 
 
636
        sigfillset(&sigs);
 
637
        sigdelset(&sigs, SIGCHLD);
 
638
        sigdelset(&sigs, SIGPIPE);
 
639
        sigdelset(&sigs, SIGTERM);
 
640
        sigdelset(&sigs, SIGINT);
 
641
        sigdelset(&sigs, SIGHUP);
 
642
 
 
643
        p.fd = sk;
 
644
        p.events = POLLIN | POLLERR | POLLHUP;
 
645
 
 
646
        memset(&s, 0, sizeof(s));
 
647
 
 
648
        while (!__io_canceled) {
 
649
                p.revents = 0;
 
650
                if (ppoll(&p, 1, NULL, &sigs) < 1)
 
651
                        continue;
 
652
 
 
653
                len = read(sk, buf, sizeof(buf));
 
654
                if (len < 0)
 
655
                        break;
 
656
 
 
657
                for (i = 0; i < len; i++)
 
658
                        celluon_decode(fd, &s, buf[i]);
 
659
        }
 
660
 
 
661
        printf("Disconnected\n");
 
662
 
 
663
        ioctl(fd, UI_DEV_DESTROY);
 
664
 
 
665
        close(fd);
 
666
        close(sk);
 
667
 
 
668
        return 0;
 
669
}