Upgrade bluez5_37 :Merge the code from private
[platform/upstream/bluez.git] / peripheral / attach.c
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2015  Intel Corporation. All rights reserved.
6  *
7  *
8  *  This library is free software; you can redistribute it and/or
9  *  modify it under the terms of the GNU Lesser General Public
10  *  License as published by the Free Software Foundation; either
11  *  version 2.1 of the License, or (at your option) any later version.
12  *
13  *  This library 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 GNU
16  *  Lesser General Public License for more details.
17  *
18  *  You should have received a copy of the GNU Lesser General Public
19  *  License along with this library; 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 #include <fcntl.h>
29 #include <unistd.h>
30 #include <sys/ioctl.h>
31
32 #include "lib/bluetooth.h"
33 #include "lib/hci.h"
34 #include "lib/hci_lib.h"
35 #include "tools/hciattach.h"
36 #include "peripheral/attach.h"
37
38 static const char *serial_dev = "/dev/ttyS1";
39 static int serial_fd = -1;
40
41 static int open_serial(const char *path)
42 {
43         struct termios ti;
44         int fd, saved_ldisc, ldisc = N_HCI;
45
46         fd = open(path, O_RDWR | O_NOCTTY);
47         if (fd < 0) {
48                 perror("Failed to open serial port");
49                 return -1;
50         }
51
52         if (tcflush(fd, TCIOFLUSH) < 0) {
53                 perror("Failed to flush serial port");
54                 close(fd);
55                 return -1;
56         }
57
58         if (ioctl(fd, TIOCGETD, &saved_ldisc) < 0) {
59                 perror("Failed get serial line discipline");
60                 close(fd);
61                 return -1;
62         }
63
64         /* Switch TTY to raw mode */
65         memset(&ti, 0, sizeof(ti));
66         cfmakeraw(&ti);
67
68         ti.c_cflag |= (B115200 | CLOCAL | CREAD);
69
70         /* Set flow control */
71         ti.c_cflag |= CRTSCTS;
72
73         if (tcsetattr(fd, TCSANOW, &ti) < 0) {
74                 perror("Failed to set serial port settings");
75                 close(fd);
76                 return -1;
77         }
78
79         if (ioctl(fd, TIOCSETD, &ldisc) < 0) {
80                 perror("Failed set serial line discipline");
81                 close(fd);
82                 return -1;
83         }
84
85         printf("Switched line discipline from %d to %d\n", saved_ldisc, ldisc);
86
87         return fd;
88 }
89
90 static int attach_proto(const char *path, unsigned int proto,
91                                                 unsigned int flags)
92 {
93         int fd, dev_id;
94
95         fd = open_serial(path);
96         if (fd < 0)
97                 return -1;
98
99         if (ioctl(fd, HCIUARTSETFLAGS, flags) < 0) {
100                 perror("Failed to set flags");
101                 close(fd);
102                 return -1;
103         }
104
105         if (ioctl(fd, HCIUARTSETPROTO, proto) < 0) {
106                 perror("Failed to set protocol");
107                 close(fd);
108                 return -1;
109         }
110
111         dev_id = ioctl(fd, HCIUARTGETDEVICE);
112         if (dev_id < 0) {
113                 perror("Failed to get device id");
114                 close(fd);
115                 return -1;
116         }
117
118         printf("Device index %d attached\n", dev_id);
119
120         return fd;
121 }
122
123 void attach_start(void)
124 {
125         unsigned long flags;
126
127         if (serial_fd >= 0)
128                 return;
129
130         printf("Attaching BR/EDR controller to %s\n", serial_dev);
131
132         flags = (1 << HCI_UART_RESET_ON_INIT);
133
134         serial_fd = attach_proto(serial_dev, HCI_UART_H4, flags);
135 }
136
137 void attach_stop(void)
138 {
139         if (serial_fd < 0)
140                 return;
141
142         close(serial_fd);
143         serial_fd = -1;
144 }