bluetooth.c revision 6e6506eb74c918e761f9ba08a6c71897334747c1
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> 216e6506eb74c918e761f9ba08a6c71897334747c1Glenn Kasten#include <stdlib.h> 227342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#include <sys/ioctl.h> 237342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#include <sys/socket.h> 247342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#include <sys/types.h> 257342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#include <sys/stat.h> 267342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 277342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#include <cutils/log.h> 287342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#include <cutils/properties.h> 297342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 307342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#include <bluetooth/bluetooth.h> 317342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#include <bluetooth/hci.h> 327342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#include <bluetooth/hci_lib.h> 337342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 347342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#include <bluedroid/bluetooth.h> 357342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 367342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#ifndef HCI_DEV_ID 377342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#define HCI_DEV_ID 0 387342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project#endif 397342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 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) { 599f71f85140223aa110f29440cfb87de2d760761aSteve Block ALOGW("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) { 869657b13bd143660e9285e9bec379eec12c866110Steve Block ALOGE("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) { 929657b13bd143660e9285e9bec379eec12c866110Steve Block ALOGE("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) { 1239657b13bd143660e9285e9bec379eec12c866110Steve Block ALOGE("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) { 1299657b13bd143660e9285e9bec379eec12c866110Steve Block ALOGE("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) { 1439657b13bd143660e9285e9bec379eec12c866110Steve Block ALOGE("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() { 150c7be2810d52c07f8cff574c93166a02f3c14d878Steve Block ALOGV(__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 15864661e48d99f432299e40bde2d11b26944a71dd4Steve Block ALOGI("Starting hciattach daemon"); 1597342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (property_set("ctl.start", "hciattach") < 0) { 1609657b13bd143660e9285e9bec379eec12c866110Steve Block ALOGE("Failed to start hciattach"); 161dad064dc614b7c582a011f0addbff2a9eb68c195Jaikumar Ganesh set_bluetooth_power(0); 1627342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 1637342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 1647342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1657342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project // Try for 10 seconds, this can only succeed once hciattach has sent the 1667342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project // firmware and then turned on hci device via HCIUARTSETPROTO ioctl 1677342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project for (attempt = 1000; attempt > 0; attempt--) { 1687342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project hci_sock = create_hci_sock(); 1697342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (hci_sock < 0) goto out; 1707342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 17104a1a722bda65ea26fc449a613085909056c1fa2Jaikumar Ganesh ret = ioctl(hci_sock, HCIDEVUP, HCI_DEV_ID); 17262432dd0bb4d59f640bde9309f86eef2fd984f18Matthew Xie 17364661e48d99f432299e40bde2d11b26944a71dd4Steve Block ALOGI("bt_enable: ret: %d, errno: %d", ret, errno); 17404a1a722bda65ea26fc449a613085909056c1fa2Jaikumar Ganesh if (!ret) { 1757342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project break; 17662432dd0bb4d59f640bde9309f86eef2fd984f18Matthew Xie } else if (errno == EALREADY) { 1779f71f85140223aa110f29440cfb87de2d760761aSteve Block ALOGW("Bluetoothd already started, unexpectedly!"); 17862432dd0bb4d59f640bde9309f86eef2fd984f18Matthew Xie break; 1797342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 18062432dd0bb4d59f640bde9309f86eef2fd984f18Matthew Xie 1817342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project close(hci_sock); 18262432dd0bb4d59f640bde9309f86eef2fd984f18Matthew Xie usleep(100000); // 100 ms retry delay 1837342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 1847342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (attempt == 0) { 1859657b13bd143660e9285e9bec379eec12c866110Steve Block ALOGE("%s: Timeout waiting for HCI device to come up, error- %d, ", 18604a1a722bda65ea26fc449a613085909056c1fa2Jaikumar Ganesh __FUNCTION__, ret); 187cd60add87bf628e96d3a91dc96d4bf945a0ccb17jhtop.kim if (property_set("ctl.stop", "hciattach") < 0) { 1889657b13bd143660e9285e9bec379eec12c866110Steve Block ALOGE("Error stopping hciattach"); 189cd60add87bf628e96d3a91dc96d4bf945a0ccb17jhtop.kim } 190dad064dc614b7c582a011f0addbff2a9eb68c195Jaikumar Ganesh set_bluetooth_power(0); 1917342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 1927342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 1937342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 19464661e48d99f432299e40bde2d11b26944a71dd4Steve Block ALOGI("Starting bluetoothd deamon"); 19512f7feb45d8bfcf8514143103ac30bc4efee26f6Jaikumar Ganesh if (property_set("ctl.start", "bluetoothd") < 0) { 1969657b13bd143660e9285e9bec379eec12c866110Steve Block ALOGE("Failed to start bluetoothd"); 197dad064dc614b7c582a011f0addbff2a9eb68c195Jaikumar Ganesh set_bluetooth_power(0); 1987342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 1997342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 2007342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2017342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ret = 0; 2027342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2037342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectout: 2047342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (hci_sock >= 0) close(hci_sock); 2057342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project return ret; 2067342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project} 2077342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2087342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectint bt_disable() { 209c7be2810d52c07f8cff574c93166a02f3c14d878Steve Block ALOGV(__FUNCTION__); 2107342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2117342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int ret = -1; 2127342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int hci_sock = -1; 2137342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 21464661e48d99f432299e40bde2d11b26944a71dd4Steve Block ALOGI("Stopping bluetoothd deamon"); 21512f7feb45d8bfcf8514143103ac30bc4efee26f6Jaikumar Ganesh if (property_set("ctl.stop", "bluetoothd") < 0) { 2169657b13bd143660e9285e9bec379eec12c866110Steve Block ALOGE("Error stopping bluetoothd"); 2177342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 2187342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 2197342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project usleep(HCID_STOP_DELAY_USEC); 2207342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2217342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project hci_sock = create_hci_sock(); 2227342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (hci_sock < 0) goto out; 2237342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ioctl(hci_sock, HCIDEVDOWN, HCI_DEV_ID); 2247342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 22564661e48d99f432299e40bde2d11b26944a71dd4Steve Block ALOGI("Stopping hciattach deamon"); 2267342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (property_set("ctl.stop", "hciattach") < 0) { 2279657b13bd143660e9285e9bec379eec12c866110Steve Block ALOGE("Error stopping hciattach"); 2287342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 2297342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 2307342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2317342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (set_bluetooth_power(0) < 0) { 2327342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 2337342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 2347342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ret = 0; 2357342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2367342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectout: 2377342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (hci_sock >= 0) close(hci_sock); 2387342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project return ret; 2397342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project} 2407342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2417342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectint bt_is_enabled() { 242c7be2810d52c07f8cff574c93166a02f3c14d878Steve Block ALOGV(__FUNCTION__); 2437342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2447342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int hci_sock = -1; 2457342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int ret = -1; 2467342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project struct hci_dev_info dev_info; 2477342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2487342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2497342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project // Check power first 2507342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ret = check_bluetooth_power(); 2517342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (ret == -1 || ret == 0) goto out; 2527342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2537342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ret = -1; 2547342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2557342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project // Power is on, now check if the HCI interface is up 2567342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project hci_sock = create_hci_sock(); 2577342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (hci_sock < 0) goto out; 2587342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2597342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project dev_info.dev_id = HCI_DEV_ID; 2607342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (ioctl(hci_sock, HCIGETDEVINFO, (void *)&dev_info) < 0) { 2617342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ret = 0; 2627342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 2637342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 2647342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2651890bf01833f6cab431f014af7a20fcbed3a4e13Jaikumar Ganesh if (dev_info.flags & (1 << (HCI_UP & 31))) { 2661890bf01833f6cab431f014af7a20fcbed3a4e13Jaikumar Ganesh ret = 1; 2671890bf01833f6cab431f014af7a20fcbed3a4e13Jaikumar Ganesh } else { 2681890bf01833f6cab431f014af7a20fcbed3a4e13Jaikumar Ganesh ret = 0; 2691890bf01833f6cab431f014af7a20fcbed3a4e13Jaikumar Ganesh } 2707342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2717342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectout: 2727342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (hci_sock >= 0) close(hci_sock); 2737342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project return ret; 2747342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project} 275a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly 276a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pellyint ba2str(const bdaddr_t *ba, char *str) { 277a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly return sprintf(str, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", 278a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly ba->b[5], ba->b[4], ba->b[3], ba->b[2], ba->b[1], ba->b[0]); 279a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly} 280a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly 281a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pellyint str2ba(const char *str, bdaddr_t *ba) { 282a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly int i; 283a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly for (i = 5; i >= 0; i--) { 2846e6506eb74c918e761f9ba08a6c71897334747c1Glenn Kasten ba->b[i] = (uint8_t) strtoul(str, (char **) &str, 16); 285a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly str++; 286a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly } 287a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly return 0; 288a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly} 289