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