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-2010 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 #define _GNU_SOURCE
31 #include <stdio.h>
32 #include <errno.h>
33 #include <fcntl.h>
34 #include <unistd.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <signal.h>
38 #include <syslog.h>
39 #include <termios.h>
40 #include <time.h>
41 #include <sys/time.h>
42 #include <sys/poll.h>
43 #include <sys/param.h>
44 #include <sys/ioctl.h>
45 #include <sys/socket.h>
46 #include <sys/uio.h>
47 #include <sys/timerfd.h>
48
49 #include "hciattach.h"
50
51 #define RFKILL_NODE "/sys/class/rfkill/rfkill0/state"
52
53 #ifdef NEED_PPOLL
54 #include "ppoll.h"
55 #endif
56
57 /* #define SCHED_ENABLE */
58
59 #ifdef SCHED_ENABLE
60 #include <sched.h>
61 #endif
62
63 struct uart_t {
64 char *type;
65 int m_id;
66 int p_id;
67 int proto;
68 int init_speed;
69 int speed;
70 int flags;
71 int pm;
72 char *bdaddr;
73 int (*init) (int fd, struct uart_t *u, struct termios *ti);
74 int (*post) (int fd, struct uart_t *u, struct termios *ti);
75 };
76
77 #define FLOW_CTL 0x0001
78 #define ENABLE_PM 1
79 #define DISABLE_PM 0
80
81 static volatile sig_atomic_t __io_canceled = 0;
82
sig_hup(int sig)83 static void sig_hup(int sig)
84 {
85 RS_INFO("signal hup.");
86 }
87
sig_term(int sig)88 static void sig_term(int sig)
89 {
90 switch (sig) {
91 case SIGINT:
92 RS_INFO("signal int.");
93 break;
94 case SIGTERM:
95 RS_INFO("signal term.");
96 break;
97 }
98 __io_canceled = 1;
99 }
100
sig_alarm(int sig)101 static void sig_alarm(int sig)
102 {
103 RS_ERR("Initialization timed out.");
104 exit(1);
105 }
106
uart_speed(int s)107 static int uart_speed(int s)
108 {
109 switch (s) {
110 case 9600:
111 return B9600;
112 case 19200:
113 return B19200;
114 case 38400:
115 return B38400;
116 case 57600:
117 return B57600;
118 case 115200:
119 return B115200;
120 case 230400:
121 return B230400;
122 case 460800:
123 return B460800;
124 case 500000:
125 return B500000;
126 case 576000:
127 return B576000;
128 case 921600:
129 return B921600;
130 case 1000000:
131 return B1000000;
132 case 1152000:
133 return B1152000;
134 case 1500000:
135 return B1500000;
136 case 2000000:
137 return B2000000;
138 #ifdef B2500000
139 case 2500000:
140 return B2500000;
141 #endif
142 #ifdef B3000000
143 case 3000000:
144 return B3000000;
145 #endif
146 #ifdef B3500000
147 case 3500000:
148 return B3500000;
149 #endif
150 #ifdef B4000000
151 case 4000000:
152 return B4000000;
153 #endif
154 default:
155 return B57600;
156 }
157 }
158
set_speed(int fd,struct termios * ti,int speed)159 int set_speed(int fd, struct termios *ti, int speed)
160 {
161 if (cfsetospeed(ti, uart_speed(speed)) < 0)
162 return -errno;
163
164 if (cfsetispeed(ti, uart_speed(speed)) < 0)
165 return -errno;
166
167 if (tcsetattr(fd, TCSANOW, ti) < 0)
168 return -errno;
169
170 return 0;
171 }
172
realtek_init(int fd,struct uart_t * u,struct termios * ti)173 static int realtek_init(int fd, struct uart_t *u, struct termios *ti)
174 {
175
176 RS_INFO("Realtek Bluetooth init uart with init speed:%d, type:HCI UART %s",
177 u->init_speed,
178 (u->proto == HCI_UART_H4) ? "H4" : "H5");
179 return rtb_init(fd, u->proto, u->speed, ti);
180 }
181
realtek_post(int fd,struct uart_t * u,struct termios * ti)182 static int realtek_post(int fd, struct uart_t *u, struct termios *ti)
183 {
184 RS_INFO("Realtek Bluetooth post process");
185 return rtb_post(fd, u->proto, ti);
186 }
187
188 struct uart_t uart[] = {
189 { "any", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, DISABLE_PM, NULL, NULL},
190
191 /* Realtek Bluetooth H4 */
192 { "rtk_h4", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, 0, DISABLE_PM, NULL, realtek_init, realtek_post },
193
194 /* Realtek Bluetooth H5 */
195 { "rtk_h5", 0x0000, 0x0000, HCI_UART_3WIRE, 115200,115200, 0, DISABLE_PM, NULL, realtek_init, realtek_post },
196
197 { NULL, 0 }
198 };
199
get_by_id(int m_id,int p_id)200 static struct uart_t * get_by_id(int m_id, int p_id)
201 {
202 int i;
203 for (i = 0; uart[i].type; i++) {
204 if (uart[i].m_id == m_id && uart[i].p_id == p_id)
205 return &uart[i];
206 }
207 return NULL;
208 }
209
get_by_type(char * type)210 static struct uart_t * get_by_type(char *type)
211 {
212 int i;
213 for (i = 0; uart[i].type; i++) {
214 if (!strcmp(uart[i].type, type))
215 return &uart[i];
216 }
217 return NULL;
218 }
219
220 /* Initialize UART driver */
init_uart(char * dev,struct uart_t * u,int send_break,int raw)221 static int init_uart(char *dev, struct uart_t *u, int send_break, int raw)
222 {
223 struct termios ti;
224 int fd, i;
225 unsigned long flags = 0;
226
227 if (raw)
228 flags |= 1 << HCI_UART_RAW_DEVICE;
229
230 fd = open(dev, O_RDWR | O_NOCTTY);
231 if (fd < 0) {
232 RS_ERR("Can't open serial port, %d, %s", errno,
233 strerror(errno));
234 return -1;
235 }
236
237 tcflush(fd, TCIOFLUSH);
238
239 if (tcgetattr(fd, &ti) < 0) {
240 RS_ERR("Can't get port settings, %d, %s", errno,
241 strerror(errno));
242 return -1;
243 }
244
245 cfmakeraw(&ti);
246
247 ti.c_cflag |= CLOCAL;
248 if (u->flags & FLOW_CTL)
249 ti.c_cflag |= CRTSCTS;
250 else
251 ti.c_cflag &= ~CRTSCTS;
252
253 if (tcsetattr(fd, TCSANOW, &ti) < 0) {
254 RS_ERR("Can't set port settings, %d, %s", errno,
255 strerror(errno));
256 return -1;
257 }
258
259 /* Set initial baudrate */
260 if (set_speed(fd, &ti, u->init_speed) < 0) {
261 RS_ERR("Can't set initial baud rate, %d, %s", errno,
262 strerror(errno));
263 return -1;
264 }
265
266 tcflush(fd, TCIOFLUSH);
267
268 if (send_break) {
269 tcsendbreak(fd, 0);
270 usleep(500000);
271 }
272
273 if (u->init && u->init(fd, u, &ti) < 0)
274 return -1;
275
276 tcflush(fd, TCIOFLUSH);
277
278 /* Set actual baudrate
279 * There is no need to change baudrate after uart init
280 * */
281 /* if (set_speed(fd, &ti, u->speed) < 0) {
282 * perror("Can't set baud rate");
283 * return -1;
284 * }
285 */
286
287 /* Set TTY to N_HCI line discipline */
288 i = N_HCI;
289 if (ioctl(fd, TIOCSETD, &i) < 0) {
290 RS_ERR("Can't set line discipline %d, %s", errno,
291 strerror(errno));
292 return -1;
293 }
294
295 if (flags && ioctl(fd, HCIUARTSETFLAGS, flags) < 0) {
296 RS_ERR("Can't set UART flags %d, %s", errno, strerror(errno));
297 return -1;
298 }
299
300 if (ioctl(fd, HCIUARTSETPROTO, u->proto) < 0) {
301 RS_ERR("Can't set device %d, %s", errno, strerror(errno));
302 return -1;
303 }
304
305 if (u->post && u->post(fd, u, &ti) < 0)
306 return -1;
307
308 return fd;
309 }
310
reset_bluetooth(void)311 static int reset_bluetooth(void)
312 {
313
314 int fd;
315 char state[2];
316 int result;
317
318 /* power off and power on BT */
319 fd = open(RFKILL_NODE, O_RDWR);
320 if (fd < 0) {
321 RS_ERR("Cannot open %s, %d %s", RFKILL_NODE, errno,
322 strerror(errno));
323 return -1;
324 }
325 state[0] = '0';
326 state[1] = '\0';
327 result = write(fd, state, strlen(state) + 1);
328 if (result != (strlen(state) + 1)) {
329 RS_ERR("Cannot write 0 to rfkill state %d %s", errno,
330 strerror(errno));
331 close(fd);
332 return -1;
333 }
334
335 usleep(500000);
336
337 state[0] = '1';
338 state[1] = '\0';
339 result = write(fd, state, strlen(state) + 1);
340 if (result != (strlen(state) + 1)) {
341 RS_ERR("Cannot write 1 to rfkill state %d %s", errno,
342 strerror(errno));
343 close(fd);
344 return -1;
345 }
346
347 usleep(500000);
348 close(fd);
349
350 return 0;
351 }
352
usage(void)353 static void usage(void)
354 {
355 RS_INFO("hciattach - HCI UART driver initialization utility");
356 RS_INFO("Usage:");
357 RS_INFO("\thciattach [-n] [-p] [-b] [-r] [-t timeout] [-s initial_speed] <tty> <type | id> [speed] [flow|noflow] [bdaddr]");
358 RS_INFO("\thciattach -l");
359 }
360
main(int argc,char * argv[])361 int main(int argc, char *argv[])
362 {
363 struct uart_t *u = NULL;
364 int detach, printpid, raw, opt, i, n, ld, err;
365 int to = 10;
366 int init_speed = 0;
367 int send_break = 0;
368 pid_t pid;
369 struct sigaction sa;
370 struct pollfd p;
371 sigset_t sigs;
372 char dev[PATH_MAX];
373 #ifdef SCHED_ENABLE
374 struct sched_param sched_par;
375 #endif
376
377 detach = 1;
378 printpid = 0;
379 raw = 0;
380
381 while ((opt=getopt(argc, argv, "bnpt:s:lr")) != EOF) {
382 switch(opt) {
383 case 'b':
384 send_break = 1;
385 break;
386
387 case 'n':
388 detach = 0;
389 break;
390
391 case 'p':
392 printpid = 1;
393 break;
394
395 case 't':
396 to = atoi(optarg);
397 break;
398
399 case 's':
400 init_speed = atoi(optarg);
401 break;
402
403 case 'l':
404 for (i = 0; uart[i].type; i++) {
405 RS_INFO("%-10s0x%04x,0x%04x", uart[i].type,
406 uart[i].m_id, uart[i].p_id);
407 }
408 exit(0);
409
410 case 'r':
411 raw = 1;
412 break;
413
414 default:
415 usage();
416 exit(1);
417 }
418 }
419
420 n = argc - optind;
421 if (n < 2) {
422 usage();
423 exit(1);
424 }
425
426 for (n = 0; optind < argc; n++, optind++) {
427 char *opt;
428
429 opt = argv[optind];
430
431 switch(n) {
432 case 0:
433 dev[0] = 0;
434 if (!strchr(opt, '/'))
435 strcpy(dev, "/dev/");
436 strcat(dev, opt);
437 break;
438
439 case 1:
440 if (strchr(argv[optind], ',')) {
441 int m_id, p_id;
442 sscanf(argv[optind], "%x,%x", &m_id, &p_id);
443 u = get_by_id(m_id, p_id);
444 } else {
445 u = get_by_type(opt);
446 }
447
448 if (!u) {
449 RS_ERR("Unknown device type or id");
450 exit(1);
451 }
452
453 break;
454
455 case 2:
456 u->speed = atoi(argv[optind]);
457 break;
458
459 case 3:
460 if (!strcmp("flow", argv[optind]))
461 u->flags |= FLOW_CTL;
462 else
463 u->flags &= ~FLOW_CTL;
464 break;
465
466 case 4:
467 if (!strcmp("sleep", argv[optind]))
468 u->pm = ENABLE_PM;
469 else
470 u->pm = DISABLE_PM;
471 break;
472
473 case 5:
474 u->bdaddr = argv[optind];
475 break;
476 }
477 }
478
479 if (!u) {
480 RS_ERR("Unknown device type or id");
481 exit(1);
482 }
483
484 start:
485
486 #ifdef SCHED_ENABLE
487 RS_INFO("Increase the priority of the process with set sched");
488 memset(&sched_par, 0, sizeof(sched_par));
489 sched_par.sched_priority = 99;
490 err = sched_setscheduler(0, SCHED_FIFO, &sched_par);
491 if (err == -1) {
492 RS_ERR("Call sched_setscheduler error, %s",
493 strerror(errno));
494 }
495 /* #else
496 * RS_INFO("Increase the priority of the process with nice");
497 * err = nice(-20);
498 * if (err == -1) {
499 * RS_ERR("Call nice error, %s", strerror(errno));
500 * }
501 */
502 #endif
503
504 /* If user specified a initial speed, use that instead of
505 the hardware's default */
506 if (init_speed)
507 u->init_speed = init_speed;
508
509 memset(&sa, 0, sizeof(sa));
510 sa.sa_flags = SA_NOCLDSTOP;
511 sa.sa_handler = sig_alarm;
512 sigaction(SIGALRM, &sa, NULL);
513
514 /* 10 seconds should be enough for initialization */
515 alarm(to);
516
517 n = init_uart(dev, u, send_break, raw);
518 if (n < 0) {
519 RS_ERR("Can't initialize device %d, %s", errno,
520 strerror(errno));
521 exit(1);
522 }
523
524 RS_INFO("Device setup complete");
525
526 alarm(0);
527
528 memset(&sa, 0, sizeof(sa));
529 sa.sa_flags = SA_NOCLDSTOP;
530 sa.sa_handler = SIG_IGN;
531 sigaction(SIGCHLD, &sa, NULL);
532 sigaction(SIGPIPE, &sa, NULL);
533
534 sa.sa_handler = sig_term;
535 sigaction(SIGTERM, &sa, NULL);
536 sigaction(SIGINT, &sa, NULL);
537
538 sa.sa_handler = sig_hup;
539 sigaction(SIGHUP, &sa, NULL);
540
541 if (detach) {
542 if ((pid = fork())) {
543 if (printpid)
544 RS_INFO("%d", pid);
545 return 0;
546 }
547
548 for (i = 0; i < 20; i++)
549 if (i != n)
550 close(i);
551 }
552
553 p.fd = n;
554 p.events = POLLERR | POLLHUP;
555
556 sigfillset(&sigs);
557 sigdelset(&sigs, SIGCHLD);
558 sigdelset(&sigs, SIGPIPE);
559 sigdelset(&sigs, SIGTERM);
560 sigdelset(&sigs, SIGINT);
561 sigdelset(&sigs, SIGHUP);
562
563 while (!__io_canceled) {
564 p.revents = 0;
565 err = ppoll(&p, 1, NULL, &sigs);
566 if (err < 0 && errno == EINTR) {
567 RS_INFO("Got EINTR.");
568 continue;
569 } if (err)
570 break;
571 }
572
573 RS_INFO("err %d, p->revents %04x", err, p.revents);
574
575 /* Restore TTY line discipline */
576 RS_INFO("Restore TTY line discipline");
577 ld = N_TTY;
578 if (ioctl(n, TIOCSETD, &ld) < 0) {
579 RS_ERR("Can't restore line discipline %d, %s", errno,
580 strerror(errno));
581 exit(1);
582 }
583
584 if (p.revents & (POLLERR | POLLHUP)) {
585 RS_INFO("Recover...");
586 reset_bluetooth();
587 goto start;
588 }
589
590 return 0;
591 }
592
util_hexdump(const uint8_t * buf,size_t len)593 void util_hexdump(const uint8_t *buf, size_t len)
594 {
595 static const char hexdigits[] = "0123456789abcdef";
596 char str[16 * 3];
597 size_t i;
598
599 if (!buf || !len)
600 return;
601
602 for (i = 0; i < len; i++) {
603 str[((i % 16) * 3)] = hexdigits[buf[i] >> 4];
604 str[((i % 16) * 3) + 1] = hexdigits[buf[i] & 0xf];
605 str[((i % 16) * 3) + 2] = ' ';
606 if ((i + 1) % 16 == 0) {
607 str[16 * 3 - 1] = '\0';
608 RS_INFO("%s", str);
609 }
610 }
611
612 if (i % 16 > 0) {
613 str[(i % 16) * 3 - 1] = '\0';
614 RS_INFO("%s", str);
615 }
616 }
617
timeout_set(int fd,unsigned int msec)618 int timeout_set(int fd, unsigned int msec)
619 {
620 struct itimerspec itimer;
621 unsigned int sec = msec / 1000;
622
623 memset(&itimer, 0, sizeof(itimer));
624 itimer.it_interval.tv_sec = 0;
625 itimer.it_interval.tv_nsec = 0;
626 itimer.it_value.tv_sec = sec;
627 itimer.it_value.tv_nsec = (msec - (sec * 1000)) * 1000 * 1000;
628
629 return timerfd_settime(fd, 0, &itimer, NULL);
630 }
631
632