bluetooth.c revision 12f7feb45d8bfcf8514143103ac30bc4efee26f6
17342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project/* 27342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 37342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project * 47342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 57342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project * you may not use this file except in compliance with the License. 67342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project * You may obtain a copy of the License at 77342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project * 87342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 97342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project * 107342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 117342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 127342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project * See the License for the specific language governing permissions and 147342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project * limitations under the License. 157342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project */ 167342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 177342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#define LOG_TAG "bluedroid" 187342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 197342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#include <errno.h> 207342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#include <fcntl.h> 217342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#include <sys/ioctl.h> 227342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#include <sys/socket.h> 237342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#include <sys/types.h> 247342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#include <sys/stat.h> 257342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 267342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#include <cutils/log.h> 277342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#include <cutils/properties.h> 287342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 297342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#include <bluetooth/bluetooth.h> 307342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#include <bluetooth/hci.h> 317342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#include <bluetooth/hci_lib.h> 327342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 337342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#include <bluedroid/bluetooth.h> 347342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 357342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#ifndef HCI_DEV_ID 367342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#define HCI_DEV_ID 0 377342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#endif 387342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 39df782f29a530d805c13f32bb43883306c05a4504The Android Open Source Project#define HCID_START_DELAY_SEC 3 407342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#define HCID_STOP_DELAY_USEC 500000 417342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 427342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#define MIN(x,y) (((x)<(y))?(x):(y)) 437342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 447342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 457342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectstatic int rfkill_id = -1; 467342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectstatic char *rfkill_state_path = NULL; 477342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 487342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 497342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectstatic int init_rfkill() { 507342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project char path[64]; 517342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project char buf[16]; 527342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int fd; 537342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int sz; 547342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int id; 557342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project for (id = 0; ; id++) { 567342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project snprintf(path, sizeof(path), "/sys/class/rfkill/rfkill%d/type", id); 577342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project fd = open(path, O_RDONLY); 587342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (fd < 0) { 597342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project LOGW("open(%s) failed: %s (%d)\n", path, strerror(errno), errno); 607342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project return -1; 617342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 627342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project sz = read(fd, &buf, sizeof(buf)); 637342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project close(fd); 647342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (sz >= 9 && memcmp(buf, "bluetooth", 9) == 0) { 657342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project rfkill_id = id; 667342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project break; 677342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 687342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 697342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 707342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project asprintf(&rfkill_state_path, "/sys/class/rfkill/rfkill%d/state", rfkill_id); 717342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project return 0; 727342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project} 737342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 747342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectstatic int check_bluetooth_power() { 757342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int sz; 767342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int fd = -1; 777342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int ret = -1; 787342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project char buffer; 797342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 807342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (rfkill_id == -1) { 817342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (init_rfkill()) goto out; 827342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 837342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 847342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project fd = open(rfkill_state_path, O_RDONLY); 857342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (fd < 0) { 867342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project LOGE("open(%s) failed: %s (%d)", rfkill_state_path, strerror(errno), 877342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project errno); 887342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 897342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 907342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project sz = read(fd, &buffer, 1); 917342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (sz != 1) { 927342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project LOGE("read(%s) failed: %s (%d)", rfkill_state_path, strerror(errno), 937342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project errno); 947342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 957342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 967342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 977342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project switch (buffer) { 987342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project case '1': 997342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ret = 1; 1007342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project break; 1017342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project case '0': 1027342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ret = 0; 1037342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project break; 1047342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 1057342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1067342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectout: 1077342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (fd >= 0) close(fd); 1087342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project return ret; 1097342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project} 1107342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1117342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectstatic int set_bluetooth_power(int on) { 1127342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int sz; 1137342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int fd = -1; 1147342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int ret = -1; 1157342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project const char buffer = (on ? '1' : '0'); 1167342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1177342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (rfkill_id == -1) { 1187342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (init_rfkill()) goto out; 1197342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 1207342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1217342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project fd = open(rfkill_state_path, O_WRONLY); 1227342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (fd < 0) { 1237342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project LOGE("open(%s) for write failed: %s (%d)", rfkill_state_path, 1247342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project strerror(errno), errno); 1257342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 1267342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 1277342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project sz = write(fd, &buffer, 1); 1287342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (sz < 0) { 1297342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project LOGE("write(%s) failed: %s (%d)", rfkill_state_path, strerror(errno), 1307342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project errno); 1317342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 1327342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 1337342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ret = 0; 1347342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1357342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectout: 1367342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (fd >= 0) close(fd); 1377342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project return ret; 1387342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project} 1397342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1407342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectstatic inline int create_hci_sock() { 1417342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); 1427342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (sk < 0) { 1437342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project LOGE("Failed to create bluetooth hci socket: %s (%d)", 1447342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project strerror(errno), errno); 1457342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 1467342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project return sk; 1477342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project} 1487342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1497342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectint bt_enable() { 1507342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project LOGV(__FUNCTION__); 1517342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1527342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int ret = -1; 1537342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int hci_sock = -1; 1547342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int attempt; 1557342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1567342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (set_bluetooth_power(1) < 0) goto out; 1577342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1587342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project LOGI("Starting hciattach daemon"); 1597342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (property_set("ctl.start", "hciattach") < 0) { 1607342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project LOGE("Failed to start hciattach"); 1617342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 1627342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 1637342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1647342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project // Try for 10 seconds, this can only succeed once hciattach has sent the 1657342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project // firmware and then turned on hci device via HCIUARTSETPROTO ioctl 1667342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project for (attempt = 1000; attempt > 0; attempt--) { 1677342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project hci_sock = create_hci_sock(); 1687342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (hci_sock < 0) goto out; 1697342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1707342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (!ioctl(hci_sock, HCIDEVUP, HCI_DEV_ID)) { 1717342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project break; 1727342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 1737342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project close(hci_sock); 1747342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project usleep(10000); // 10 ms retry delay 1757342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 1767342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (attempt == 0) { 1777342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project LOGE("%s: Timeout waiting for HCI device to come up", __FUNCTION__); 1787342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 1797342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 1807342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 18112f7feb45d8bfcf8514143103ac30bc4efee26f6Jaikumar Ganesh LOGI("Starting bluetoothd deamon"); 18212f7feb45d8bfcf8514143103ac30bc4efee26f6Jaikumar Ganesh if (property_set("ctl.start", "bluetoothd") < 0) { 18312f7feb45d8bfcf8514143103ac30bc4efee26f6Jaikumar Ganesh LOGE("Failed to start bluetoothd"); 1847342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 1857342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 1867342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project sleep(HCID_START_DELAY_SEC); 1877342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1887342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ret = 0; 1897342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1907342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectout: 1917342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (hci_sock >= 0) close(hci_sock); 1927342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project return ret; 1937342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project} 1947342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1957342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectint bt_disable() { 1967342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project LOGV(__FUNCTION__); 1977342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1987342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int ret = -1; 1997342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int hci_sock = -1; 2007342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 20112f7feb45d8bfcf8514143103ac30bc4efee26f6Jaikumar Ganesh LOGI("Stopping bluetoothd deamon"); 20212f7feb45d8bfcf8514143103ac30bc4efee26f6Jaikumar Ganesh if (property_set("ctl.stop", "bluetoothd") < 0) { 20312f7feb45d8bfcf8514143103ac30bc4efee26f6Jaikumar Ganesh LOGE("Error stopping bluetoothd"); 2047342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 2057342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 2067342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project usleep(HCID_STOP_DELAY_USEC); 2077342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2087342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project hci_sock = create_hci_sock(); 2097342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (hci_sock < 0) goto out; 2107342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ioctl(hci_sock, HCIDEVDOWN, HCI_DEV_ID); 2117342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2127342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project LOGI("Stopping hciattach deamon"); 2137342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (property_set("ctl.stop", "hciattach") < 0) { 2147342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project LOGE("Error stopping hciattach"); 2157342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 2167342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 2177342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2187342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (set_bluetooth_power(0) < 0) { 2197342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 2207342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 2217342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ret = 0; 2227342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2237342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectout: 2247342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (hci_sock >= 0) close(hci_sock); 2257342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project return ret; 2267342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project} 2277342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2287342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectint bt_is_enabled() { 2297342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project LOGV(__FUNCTION__); 2307342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2317342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int hci_sock = -1; 2327342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int ret = -1; 2337342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project struct hci_dev_info dev_info; 2347342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2357342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2367342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project // Check power first 2377342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ret = check_bluetooth_power(); 2387342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (ret == -1 || ret == 0) goto out; 2397342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2407342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ret = -1; 2417342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2427342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project // Power is on, now check if the HCI interface is up 2437342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project hci_sock = create_hci_sock(); 2447342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (hci_sock < 0) goto out; 2457342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2467342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project dev_info.dev_id = HCI_DEV_ID; 2477342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (ioctl(hci_sock, HCIGETDEVINFO, (void *)&dev_info) < 0) { 2487342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ret = 0; 2497342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 2507342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 2517342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2527342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ret = hci_test_bit(HCI_UP, &dev_info.flags); 2537342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2547342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectout: 2557342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (hci_sock >= 0) close(hci_sock); 2567342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project return ret; 2577342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project} 258