bluetooth.c revision 64661e48d99f432299e40bde2d11b26944a71dd4
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 397342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#define HCID_STOP_DELAY_USEC 500000 407342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 417342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#define MIN(x,y) (((x)<(y))?(x):(y)) 427342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 437342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 447342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectstatic int rfkill_id = -1; 457342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectstatic char *rfkill_state_path = NULL; 467342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 477342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 487342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectstatic int init_rfkill() { 497342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project char path[64]; 507342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project char buf[16]; 517342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int fd; 527342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int sz; 537342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int id; 547342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project for (id = 0; ; id++) { 557342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project snprintf(path, sizeof(path), "/sys/class/rfkill/rfkill%d/type", id); 567342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project fd = open(path, O_RDONLY); 577342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (fd < 0) { 587342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project LOGW("open(%s) failed: %s (%d)\n", path, strerror(errno), errno); 597342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project return -1; 607342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 617342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project sz = read(fd, &buf, sizeof(buf)); 627342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project close(fd); 637342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (sz >= 9 && memcmp(buf, "bluetooth", 9) == 0) { 647342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project rfkill_id = id; 657342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project break; 667342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 677342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 687342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 697342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project asprintf(&rfkill_state_path, "/sys/class/rfkill/rfkill%d/state", rfkill_id); 707342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project return 0; 717342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project} 727342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 737342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectstatic int check_bluetooth_power() { 747342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int sz; 757342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int fd = -1; 767342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int ret = -1; 777342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project char buffer; 787342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 797342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (rfkill_id == -1) { 807342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (init_rfkill()) goto out; 817342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 827342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 837342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project fd = open(rfkill_state_path, O_RDONLY); 847342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (fd < 0) { 857342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project LOGE("open(%s) failed: %s (%d)", rfkill_state_path, strerror(errno), 867342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project errno); 877342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 887342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 897342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project sz = read(fd, &buffer, 1); 907342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (sz != 1) { 917342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project LOGE("read(%s) failed: %s (%d)", rfkill_state_path, strerror(errno), 927342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project errno); 937342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 947342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 957342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 967342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project switch (buffer) { 977342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project case '1': 987342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ret = 1; 997342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project break; 1007342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project case '0': 1017342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ret = 0; 1027342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project break; 1037342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 1047342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1057342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectout: 1067342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (fd >= 0) close(fd); 1077342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project return ret; 1087342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project} 1097342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1107342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectstatic int set_bluetooth_power(int on) { 1117342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int sz; 1127342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int fd = -1; 1137342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int ret = -1; 1147342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project const char buffer = (on ? '1' : '0'); 1157342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1167342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (rfkill_id == -1) { 1177342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (init_rfkill()) goto out; 1187342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 1197342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1207342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project fd = open(rfkill_state_path, O_WRONLY); 1217342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (fd < 0) { 1227342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project LOGE("open(%s) for write failed: %s (%d)", rfkill_state_path, 1237342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project strerror(errno), errno); 1247342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 1257342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 1267342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project sz = write(fd, &buffer, 1); 1277342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (sz < 0) { 1287342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project LOGE("write(%s) failed: %s (%d)", rfkill_state_path, strerror(errno), 1297342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project errno); 1307342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 1317342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 1327342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ret = 0; 1337342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1347342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectout: 1357342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (fd >= 0) close(fd); 1367342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project return ret; 1377342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project} 1387342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1397342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectstatic inline int create_hci_sock() { 1407342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); 1417342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (sk < 0) { 1427342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project LOGE("Failed to create bluetooth hci socket: %s (%d)", 1437342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project strerror(errno), errno); 1447342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 1457342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project return sk; 1467342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project} 1477342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1487342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectint bt_enable() { 149c7be2810d52c07f8cff574c93166a02f3c14d878Steve Block ALOGV(__FUNCTION__); 1507342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1517342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int ret = -1; 1527342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int hci_sock = -1; 1537342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int attempt; 1547342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1557342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (set_bluetooth_power(1) < 0) goto out; 1567342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 15764661e48d99f432299e40bde2d11b26944a71dd4Steve Block ALOGI("Starting hciattach daemon"); 1587342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (property_set("ctl.start", "hciattach") < 0) { 1597342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project LOGE("Failed to start hciattach"); 160dad064dc614b7c582a011f0addbff2a9eb68c195Jaikumar Ganesh set_bluetooth_power(0); 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 17004a1a722bda65ea26fc449a613085909056c1fa2Jaikumar Ganesh ret = ioctl(hci_sock, HCIDEVUP, HCI_DEV_ID); 17162432dd0bb4d59f640bde9309f86eef2fd984f18Matthew Xie 17264661e48d99f432299e40bde2d11b26944a71dd4Steve Block ALOGI("bt_enable: ret: %d, errno: %d", ret, errno); 17304a1a722bda65ea26fc449a613085909056c1fa2Jaikumar Ganesh if (!ret) { 1747342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project break; 17562432dd0bb4d59f640bde9309f86eef2fd984f18Matthew Xie } else if (errno == EALREADY) { 17662432dd0bb4d59f640bde9309f86eef2fd984f18Matthew Xie LOGW("Bluetoothd already started, unexpectedly!"); 17762432dd0bb4d59f640bde9309f86eef2fd984f18Matthew Xie break; 1787342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 17962432dd0bb4d59f640bde9309f86eef2fd984f18Matthew Xie 1807342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project close(hci_sock); 18162432dd0bb4d59f640bde9309f86eef2fd984f18Matthew Xie usleep(100000); // 100 ms retry delay 1827342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 1837342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (attempt == 0) { 18404a1a722bda65ea26fc449a613085909056c1fa2Jaikumar Ganesh LOGE("%s: Timeout waiting for HCI device to come up, error- %d, ", 18504a1a722bda65ea26fc449a613085909056c1fa2Jaikumar Ganesh __FUNCTION__, ret); 186cd60add87bf628e96d3a91dc96d4bf945a0ccb17jhtop.kim if (property_set("ctl.stop", "hciattach") < 0) { 187cd60add87bf628e96d3a91dc96d4bf945a0ccb17jhtop.kim LOGE("Error stopping hciattach"); 188cd60add87bf628e96d3a91dc96d4bf945a0ccb17jhtop.kim } 189dad064dc614b7c582a011f0addbff2a9eb68c195Jaikumar Ganesh set_bluetooth_power(0); 1907342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 1917342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 1927342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 19364661e48d99f432299e40bde2d11b26944a71dd4Steve Block ALOGI("Starting bluetoothd deamon"); 19412f7feb45d8bfcf8514143103ac30bc4efee26f6Jaikumar Ganesh if (property_set("ctl.start", "bluetoothd") < 0) { 19512f7feb45d8bfcf8514143103ac30bc4efee26f6Jaikumar Ganesh LOGE("Failed to start bluetoothd"); 196dad064dc614b7c582a011f0addbff2a9eb68c195Jaikumar Ganesh set_bluetooth_power(0); 1977342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 1987342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 1997342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2007342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ret = 0; 2017342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2027342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectout: 2037342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (hci_sock >= 0) close(hci_sock); 2047342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project return ret; 2057342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project} 2067342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2077342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectint bt_disable() { 208c7be2810d52c07f8cff574c93166a02f3c14d878Steve Block ALOGV(__FUNCTION__); 2097342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2107342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int ret = -1; 2117342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int hci_sock = -1; 2127342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 21364661e48d99f432299e40bde2d11b26944a71dd4Steve Block ALOGI("Stopping bluetoothd deamon"); 21412f7feb45d8bfcf8514143103ac30bc4efee26f6Jaikumar Ganesh if (property_set("ctl.stop", "bluetoothd") < 0) { 21512f7feb45d8bfcf8514143103ac30bc4efee26f6Jaikumar Ganesh LOGE("Error stopping bluetoothd"); 2167342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 2177342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 2187342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project usleep(HCID_STOP_DELAY_USEC); 2197342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2207342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project hci_sock = create_hci_sock(); 2217342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (hci_sock < 0) goto out; 2227342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ioctl(hci_sock, HCIDEVDOWN, HCI_DEV_ID); 2237342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 22464661e48d99f432299e40bde2d11b26944a71dd4Steve Block ALOGI("Stopping hciattach deamon"); 2257342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (property_set("ctl.stop", "hciattach") < 0) { 2267342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project LOGE("Error stopping hciattach"); 2277342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 2287342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 2297342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2307342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (set_bluetooth_power(0) < 0) { 2317342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 2327342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 2337342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ret = 0; 2347342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2357342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectout: 2367342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (hci_sock >= 0) close(hci_sock); 2377342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project return ret; 2387342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project} 2397342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2407342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectint bt_is_enabled() { 241c7be2810d52c07f8cff574c93166a02f3c14d878Steve Block ALOGV(__FUNCTION__); 2427342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2437342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int hci_sock = -1; 2447342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int ret = -1; 2457342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project struct hci_dev_info dev_info; 2467342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2477342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2487342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project // Check power first 2497342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ret = check_bluetooth_power(); 2507342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (ret == -1 || ret == 0) goto out; 2517342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2527342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ret = -1; 2537342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2547342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project // Power is on, now check if the HCI interface is up 2557342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project hci_sock = create_hci_sock(); 2567342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (hci_sock < 0) goto out; 2577342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2587342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project dev_info.dev_id = HCI_DEV_ID; 2597342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (ioctl(hci_sock, HCIGETDEVINFO, (void *)&dev_info) < 0) { 2607342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ret = 0; 2617342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 2627342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 2637342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2641890bf01833f6cab431f014af7a20fcbed3a4e13Jaikumar Ganesh if (dev_info.flags & (1 << (HCI_UP & 31))) { 2651890bf01833f6cab431f014af7a20fcbed3a4e13Jaikumar Ganesh ret = 1; 2661890bf01833f6cab431f014af7a20fcbed3a4e13Jaikumar Ganesh } else { 2671890bf01833f6cab431f014af7a20fcbed3a4e13Jaikumar Ganesh ret = 0; 2681890bf01833f6cab431f014af7a20fcbed3a4e13Jaikumar Ganesh } 2697342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2707342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectout: 2717342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (hci_sock >= 0) close(hci_sock); 2727342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project return ret; 2737342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project} 274a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly 275a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pellyint ba2str(const bdaddr_t *ba, char *str) { 276a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly return sprintf(str, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", 277a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly ba->b[5], ba->b[4], ba->b[3], ba->b[2], ba->b[1], ba->b[0]); 278a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly} 279a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly 280a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pellyint str2ba(const char *str, bdaddr_t *ba) { 281a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly int i; 282a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly for (i = 5; i >= 0; i--) { 283a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly ba->b[i] = (uint8_t) strtoul(str, &str, 16); 284a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly str++; 285a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly } 286a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly return 0; 287a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly} 288