hci_layer_linux.cc revision 8342d95fa54d333c283ab4c16960be73392e86eb
1/**********************************************************************
2 *
3 *  Copyright (C) 2017 The Android Open Source Project
4 *  Copyright (C) 2015 Intel Corporation
5 *
6 *  Licensed under the Apache License, Version 2.0 (the "License");
7 *  you may not use this file except in compliance with the License.
8 *  You may obtain a copy of the License at:
9 *
10 *  http://www.apache.org/licenses/LICENSE-2.0
11 *
12 *  Unless required by applicable law or agreed to in writing, software
13 *  distributed under the License is distributed on an "AS IS" BASIS,
14 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15 *  implied.
16 *  See the License for the specific language governing permissions and
17 *  limitations under the License.
18 *
19 **********************************************************************/
20#include <base/bind.h>
21#include <base/logging.h>
22#include <base/threading/thread.h>
23#include <errno.h>
24#include <fcntl.h>
25#include <poll.h>
26#include <stdbool.h>
27#include <stdint.h>
28#include <stdlib.h>
29#include <string.h>
30#include <algorithm>
31
32#include <sys/ioctl.h>
33#include <sys/socket.h>
34
35#include "buffer_allocator.h"
36#include "hci_internals.h"
37#include "hci_layer.h"
38#include "osi/include/compat.h"
39#include "osi/include/log.h"
40#include "osi/include/osi.h"
41#include "osi/include/properties.h"
42
43using base::Thread;
44
45#define BTPROTO_HCI 1
46#define HCI_CHANNEL_USER 1
47#define HCI_CHANNEL_CONTROL 3
48#define HCI_DEV_NONE 0xffff
49
50#define RFKILL_TYPE_BLUETOOTH 2
51#define RFKILL_OP_CHANGE_ALL 3
52
53#define MGMT_OP_INDEX_LIST 0x0003
54#define MGMT_EV_INDEX_ADDED 0x0004
55#define MGMT_EV_COMMAND_COMP 0x0001
56#define MGMT_EV_SIZE_MAX 1024
57#define MGMT_EV_POLL_TIMEOUT 3000 /* 3000ms */
58
59struct sockaddr_hci {
60  sa_family_t hci_family;
61  unsigned short hci_dev;
62  unsigned short hci_channel;
63};
64
65struct rfkill_event {
66  uint32_t idx;
67  uint8_t type;
68  uint8_t op;
69  uint8_t soft, hard;
70} __attribute__((packed));
71
72struct mgmt_pkt {
73  uint16_t opcode;
74  uint16_t index;
75  uint16_t len;
76  uint8_t data[MGMT_EV_SIZE_MAX];
77} __attribute__((packed));
78
79struct mgmt_event_read_index {
80  uint16_t cc_opcode;
81  uint8_t status;
82  uint16_t num_intf;
83  uint16_t index[0];
84} __attribute__((packed));
85
86enum HciPacketType {
87  HCI_PACKET_TYPE_UNKNOWN = 0,
88  HCI_PACKET_TYPE_COMMAND = 1,
89  HCI_PACKET_TYPE_ACL_DATA = 2,
90  HCI_PACKET_TYPE_SCO_DATA = 3,
91  HCI_PACKET_TYPE_EVENT = 4
92};
93
94extern void initialization_complete();
95extern void hci_event_received(BT_HDR* packet);
96extern void acl_event_received(BT_HDR* packet);
97extern void sco_data_received(BT_HDR* packet);
98
99static int bt_vendor_fd = -1;
100static int hci_interface;
101static int rfkill_en;
102static int wait_hcidev(void);
103static int rfkill(int block);
104
105int reader_thread_ctrl_fd = -1;
106Thread* reader_thread = NULL;
107
108void monitor_socket(int ctrl_fd, int fd) {
109  const allocator_t* buffer_allocator = buffer_allocator_get_interface();
110  const size_t buf_size = 2000;
111  uint8_t buf[buf_size];
112  ssize_t len = read(fd, buf, buf_size);
113
114  while (len > 0) {
115    if (len == buf_size)
116      LOG(FATAL) << "This packet filled buffer, if it have continuation we "
117                    "don't know how to merge it, increase buffer size!";
118
119    uint8_t type = buf[0];
120
121    size_t packet_size = buf_size + BT_HDR_SIZE;
122    BT_HDR* packet =
123        reinterpret_cast<BT_HDR*>(buffer_allocator->alloc(packet_size));
124    packet->offset = 0;
125    packet->layer_specific = 0;
126    packet->len = len - 1;
127    memcpy(packet->data, buf + 1, len - 1);
128
129    switch (type) {
130      case HCI_PACKET_TYPE_COMMAND:
131        packet->event = MSG_HC_TO_STACK_HCI_EVT;
132        hci_event_received(packet);
133        break;
134      case HCI_PACKET_TYPE_ACL_DATA:
135        packet->event = MSG_HC_TO_STACK_HCI_ACL;
136        acl_event_received(packet);
137        break;
138      case HCI_PACKET_TYPE_SCO_DATA:
139        packet->event = MSG_HC_TO_STACK_HCI_SCO;
140        sco_data_received(packet);
141        break;
142      case HCI_PACKET_TYPE_EVENT:
143        packet->event = MSG_HC_TO_STACK_HCI_EVT;
144        hci_event_received(packet);
145        break;
146      default:
147        LOG(FATAL) << "Unexpected event type: " << +type;
148        break;
149    }
150
151    fd_set fds;
152    FD_ZERO(&fds);
153    FD_SET(ctrl_fd, &fds);
154    FD_SET(fd, &fds);
155    int res = select(std::max(fd, ctrl_fd) + 1, &fds, NULL, NULL, NULL);
156    if (res <= 0) LOG(INFO) << "Nothing more to read";
157
158    if (FD_ISSET(ctrl_fd, &fds)) {
159      LOG(INFO) << "exitting";
160      return;
161    }
162
163    len = read(fd, buf, buf_size);
164  }
165}
166
167/* TODO: should thread the device waiting and return immedialty */
168void hci_initialize() {
169  LOG(INFO) << __func__;
170
171  char prop_value[PROPERTY_VALUE_MAX];
172  osi_property_get("bluetooth.interface", prop_value, "0");
173
174  errno = 0;
175  if (memcmp(prop_value, "hci", 3))
176    hci_interface = strtol(prop_value, NULL, 10);
177  else
178    hci_interface = strtol(prop_value + 3, NULL, 10);
179  if (errno) hci_interface = 0;
180
181  LOG(INFO) << "Using interface hci" << +hci_interface;
182
183  osi_property_get("bluetooth.rfkill", prop_value, "1");
184
185  rfkill_en = atoi(prop_value);
186  if (rfkill_en) {
187    rfkill(0);
188  }
189
190  int fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
191  CHECK(fd >= 0) << "socket create error" << strerror(errno);
192
193  bt_vendor_fd = fd;
194
195  if (wait_hcidev()) {
196    LOG(FATAL) << "HCI interface hci" << +hci_interface << " not found";
197  }
198
199  struct sockaddr_hci addr;
200  memset(&addr, 0, sizeof(addr));
201  addr.hci_family = AF_BLUETOOTH;
202  addr.hci_dev = hci_interface;
203  addr.hci_channel = HCI_CHANNEL_USER;
204  if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
205    LOG(FATAL) << "socket bind error " << strerror(errno);
206  }
207
208  int sv[2];
209  if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) < 0) {
210    LOG(FATAL) << "socketpair failed: " << strerror(errno);
211  }
212
213  reader_thread_ctrl_fd = sv[0];
214  reader_thread = new Thread("hci_sock_reader");
215  reader_thread->Start();
216  reader_thread->task_runner()->PostTask(
217      FROM_HERE, base::Bind(&monitor_socket, sv[1], bt_vendor_fd));
218
219  LOG(INFO) << "HCI device ready";
220  initialization_complete();
221}
222
223void hci_close() {
224  LOG(INFO) << __func__;
225
226  if (bt_vendor_fd != -1) {
227    close(bt_vendor_fd);
228    bt_vendor_fd = -1;
229  }
230
231  if (reader_thread_ctrl_fd != -1) {
232    uint8_t msg[] = {1};
233    send(reader_thread_ctrl_fd, msg, sizeof(msg), 0);
234    reader_thread_ctrl_fd = -1;
235  }
236
237  if (reader_thread != NULL) {
238    reader_thread->Stop();
239    delete reader_thread;
240    reader_thread = NULL;
241  }
242
243  rfkill(1);
244}
245
246void hci_transmit(BT_HDR* packet) {
247  uint8_t type;
248
249  CHECK(bt_vendor_fd != -1);
250
251  uint16_t event = packet->event & MSG_EVT_MASK;
252  switch (event & MSG_EVT_MASK) {
253    case MSG_STACK_TO_HC_HCI_CMD:
254      type = 1;
255      break;
256    case MSG_STACK_TO_HC_HCI_ACL:
257      type = 2;
258      break;
259    case MSG_STACK_TO_HC_HCI_SCO:
260      type = 3;
261      break;
262    default:
263      LOG(FATAL) << "Unknown packet type " << event;
264      break;
265  }
266
267  uint8_t* addr = packet->data + packet->offset - 1;
268  uint8_t store = *addr;
269  *addr = type;
270  size_t ret = write(bt_vendor_fd, addr, packet->len + 1);
271
272  *(addr) = store;
273
274  if (ret != packet->len + 1) LOG(ERROR) << "Should have send whole packet";
275
276  if (ret == -1) LOG(FATAL) << strerror(errno);
277}
278
279static int wait_hcidev(void) {
280  struct sockaddr_hci addr;
281  struct pollfd fds[1];
282  struct mgmt_pkt ev;
283  int fd;
284  int ret = 0;
285
286  LOG(INFO) << __func__;
287
288  fd = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
289  if (fd < 0) {
290    LOG(ERROR) << "Bluetooth socket error: %s" << strerror(errno);
291    return -1;
292  }
293
294  memset(&addr, 0, sizeof(addr));
295  addr.hci_family = AF_BLUETOOTH;
296  addr.hci_dev = HCI_DEV_NONE;
297  addr.hci_channel = HCI_CHANNEL_CONTROL;
298
299  if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
300    LOG(ERROR) << "HCI Channel Control: " << strerror(errno);
301    close(fd);
302    return -1;
303  }
304
305  fds[0].fd = fd;
306  fds[0].events = POLLIN;
307
308  /* Read Controller Index List Command */
309  ev.opcode = MGMT_OP_INDEX_LIST;
310  ev.index = HCI_DEV_NONE;
311  ev.len = 0;
312
313  ssize_t wrote;
314  OSI_NO_INTR(wrote = write(fd, &ev, 6));
315  if (wrote != 6) {
316    LOG(ERROR) << "Unable to write mgmt command: " << strerror(errno);
317    ret = -1;
318    goto end;
319  }
320
321  while (1) {
322    int n;
323    OSI_NO_INTR(n = poll(fds, 1, MGMT_EV_POLL_TIMEOUT));
324    if (n == -1) {
325      LOG(ERROR) << "Poll error: " << strerror(errno);
326      ret = -1;
327      break;
328    } else if (n == 0) {
329      LOG(ERROR) << "Timeout, no HCI device detected";
330      ret = -1;
331      break;
332    }
333
334    if (fds[0].revents & POLLIN) {
335      OSI_NO_INTR(n = read(fd, &ev, sizeof(struct mgmt_pkt)));
336      if (n < 0) {
337        LOG(ERROR) << "Error reading control channel: " << strerror(errno);
338        ret = -1;
339        break;
340      }
341
342      if (ev.opcode == MGMT_EV_INDEX_ADDED && ev.index == hci_interface) {
343        goto end;
344      } else if (ev.opcode == MGMT_EV_COMMAND_COMP) {
345        struct mgmt_event_read_index* cc;
346        int i;
347
348        cc = (struct mgmt_event_read_index*)ev.data;
349
350        if (cc->cc_opcode != MGMT_OP_INDEX_LIST || cc->status != 0) continue;
351
352        for (i = 0; i < cc->num_intf; i++) {
353          if (cc->index[i] == hci_interface) goto end;
354        }
355      }
356    }
357  }
358
359end:
360  close(fd);
361  return ret;
362}
363
364static int rfkill(int block) {
365  struct rfkill_event event;
366  int fd;
367
368  LOG(INFO) << __func__;
369
370  fd = open("/dev/rfkill", O_WRONLY);
371  if (fd < 0) {
372    LOG(ERROR) << "Unable to open /dev/rfkill";
373    return -1;
374  }
375
376  memset(&event, 0, sizeof(struct rfkill_event));
377  event.op = RFKILL_OP_CHANGE_ALL;
378  event.type = RFKILL_TYPE_BLUETOOTH;
379  event.hard = block;
380  event.soft = block;
381
382  ssize_t len;
383  OSI_NO_INTR(len = write(fd, &event, sizeof(event)));
384  if (len < 0) {
385    LOG(ERROR) << "Failed to change rfkill state";
386    close(fd);
387    return 1;
388  }
389
390  close(fd);
391  return 0;
392}
393