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 483a293d2850d4530054cdcc78a4a747d6c4f0fff1jeonghoon.lim#ifndef BLUETOOTH_DOES_NOT_USE_RFKILL 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} 1393a293d2850d4530054cdcc78a4a747d6c4f0fff1jeonghoon.lim#endif 1407342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1417342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectstatic inline int create_hci_sock() { 1427342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); 1437342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (sk < 0) { 1449657b13bd143660e9285e9bec379eec12c866110Steve Block ALOGE("Failed to create bluetooth hci socket: %s (%d)", 1457342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project strerror(errno), errno); 1467342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 1477342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project return sk; 1487342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project} 1497342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1507342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectint bt_enable() { 151c7be2810d52c07f8cff574c93166a02f3c14d878Steve Block ALOGV(__FUNCTION__); 1527342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1537342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int ret = -1; 1547342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int hci_sock = -1; 1557342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int attempt; 1567342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1573a293d2850d4530054cdcc78a4a747d6c4f0fff1jeonghoon.lim#ifndef BLUETOOTH_DOES_NOT_USE_RFKILL 1587342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (set_bluetooth_power(1) < 0) goto out; 1593a293d2850d4530054cdcc78a4a747d6c4f0fff1jeonghoon.lim#endif 1607342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1613a293d2850d4530054cdcc78a4a747d6c4f0fff1jeonghoon.lim#ifndef BLUETOOTH_HCIATTACH_USING_PROPERTY 16264661e48d99f432299e40bde2d11b26944a71dd4Steve Block ALOGI("Starting hciattach daemon"); 1633a293d2850d4530054cdcc78a4a747d6c4f0fff1jeonghoon.lim if (property_set("ctl.start", "hciattach") < 0) 1643a293d2850d4530054cdcc78a4a747d6c4f0fff1jeonghoon.lim#else 1653a293d2850d4530054cdcc78a4a747d6c4f0fff1jeonghoon.lim ALOGI("Enable hci tranport"); 1663a293d2850d4530054cdcc78a4a747d6c4f0fff1jeonghoon.lim if (property_set("bluetooth.hciattach", "true") < 0) 1673a293d2850d4530054cdcc78a4a747d6c4f0fff1jeonghoon.lim#endif 1683a293d2850d4530054cdcc78a4a747d6c4f0fff1jeonghoon.lim { 1699657b13bd143660e9285e9bec379eec12c866110Steve Block ALOGE("Failed to start hciattach"); 1703a293d2850d4530054cdcc78a4a747d6c4f0fff1jeonghoon.lim#ifndef BLUETOOTH_DOES_NOT_USE_RFKILL 171dad064dc614b7c582a011f0addbff2a9eb68c195Jaikumar Ganesh set_bluetooth_power(0); 1723a293d2850d4530054cdcc78a4a747d6c4f0fff1jeonghoon.lim#endif 1737342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 1747342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 1757342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 1767342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project // Try for 10 seconds, this can only succeed once hciattach has sent the 1777342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project // firmware and then turned on hci device via HCIUARTSETPROTO ioctl 178bf6696874d1b57ffddc7848450b20e926ad5d0a4Elliott Hughes for (attempt = 100; attempt > 0; attempt--) { 1797342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project hci_sock = create_hci_sock(); 1807342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (hci_sock < 0) goto out; 1817342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 18204a1a722bda65ea26fc449a613085909056c1fa2Jaikumar Ganesh ret = ioctl(hci_sock, HCIDEVUP, HCI_DEV_ID); 18362432dd0bb4d59f640bde9309f86eef2fd984f18Matthew Xie 18404a1a722bda65ea26fc449a613085909056c1fa2Jaikumar Ganesh if (!ret) { 1857342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project break; 18662432dd0bb4d59f640bde9309f86eef2fd984f18Matthew Xie } else if (errno == EALREADY) { 1879f71f85140223aa110f29440cfb87de2d760761aSteve Block ALOGW("Bluetoothd already started, unexpectedly!"); 18862432dd0bb4d59f640bde9309f86eef2fd984f18Matthew Xie break; 1897342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 19062432dd0bb4d59f640bde9309f86eef2fd984f18Matthew Xie 191bf6696874d1b57ffddc7848450b20e926ad5d0a4Elliott Hughes ALOGI("%s: ioctl(%d, HCIDEVUP, HCI_DEV_ID) failed: %s (%d)", 192bf6696874d1b57ffddc7848450b20e926ad5d0a4Elliott Hughes __FUNCTION__, hci_sock, strerror(errno), errno); 193bf6696874d1b57ffddc7848450b20e926ad5d0a4Elliott Hughes 1947342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project close(hci_sock); 195bf6696874d1b57ffddc7848450b20e926ad5d0a4Elliott Hughes usleep(100 * 1000); // 100 ms retry delay 1967342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 1977342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (attempt == 0) { 1989657b13bd143660e9285e9bec379eec12c866110Steve Block ALOGE("%s: Timeout waiting for HCI device to come up, error- %d, ", 19904a1a722bda65ea26fc449a613085909056c1fa2Jaikumar Ganesh __FUNCTION__, ret); 200cd60add87bf628e96d3a91dc96d4bf945a0ccb17jhtop.kim if (property_set("ctl.stop", "hciattach") < 0) { 2019657b13bd143660e9285e9bec379eec12c866110Steve Block ALOGE("Error stopping hciattach"); 202cd60add87bf628e96d3a91dc96d4bf945a0ccb17jhtop.kim } 2033a293d2850d4530054cdcc78a4a747d6c4f0fff1jeonghoon.lim#ifndef BLUETOOTH_DOES_NOT_USE_RFKILL 204dad064dc614b7c582a011f0addbff2a9eb68c195Jaikumar Ganesh set_bluetooth_power(0); 2053a293d2850d4530054cdcc78a4a747d6c4f0fff1jeonghoon.lim#endif 2067342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 2077342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 2087342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 20964661e48d99f432299e40bde2d11b26944a71dd4Steve Block ALOGI("Starting bluetoothd deamon"); 21012f7feb45d8bfcf8514143103ac30bc4efee26f6Jaikumar Ganesh if (property_set("ctl.start", "bluetoothd") < 0) { 2119657b13bd143660e9285e9bec379eec12c866110Steve Block ALOGE("Failed to start bluetoothd"); 2123a293d2850d4530054cdcc78a4a747d6c4f0fff1jeonghoon.lim#ifndef BLUETOOTH_DOES_NOT_USE_RFKILL 213dad064dc614b7c582a011f0addbff2a9eb68c195Jaikumar Ganesh set_bluetooth_power(0); 2143a293d2850d4530054cdcc78a4a747d6c4f0fff1jeonghoon.lim#endif 2157342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 2167342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 2177342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2187342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ret = 0; 2197342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2207342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectout: 2217342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (hci_sock >= 0) close(hci_sock); 2227342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project return ret; 2237342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project} 2247342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2257342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectint bt_disable() { 226c7be2810d52c07f8cff574c93166a02f3c14d878Steve Block ALOGV(__FUNCTION__); 2277342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2287342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int ret = -1; 2297342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int hci_sock = -1; 2307342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 23164661e48d99f432299e40bde2d11b26944a71dd4Steve Block ALOGI("Stopping bluetoothd deamon"); 23212f7feb45d8bfcf8514143103ac30bc4efee26f6Jaikumar Ganesh if (property_set("ctl.stop", "bluetoothd") < 0) { 2339657b13bd143660e9285e9bec379eec12c866110Steve Block ALOGE("Error stopping bluetoothd"); 2347342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 2357342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 2367342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project usleep(HCID_STOP_DELAY_USEC); 2377342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2387342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project hci_sock = create_hci_sock(); 2397342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (hci_sock < 0) goto out; 2407342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ioctl(hci_sock, HCIDEVDOWN, HCI_DEV_ID); 2417342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2423a293d2850d4530054cdcc78a4a747d6c4f0fff1jeonghoon.lim#ifndef BLUETOOTH_HCIATTACH_USING_PROPERTY 24364661e48d99f432299e40bde2d11b26944a71dd4Steve Block ALOGI("Stopping hciattach deamon"); 2443a293d2850d4530054cdcc78a4a747d6c4f0fff1jeonghoon.lim if (property_set("ctl.stop", "hciattach") < 0) 2453a293d2850d4530054cdcc78a4a747d6c4f0fff1jeonghoon.lim#else 2463a293d2850d4530054cdcc78a4a747d6c4f0fff1jeonghoon.lim ALOGI("Disable hci tranport"); 2473a293d2850d4530054cdcc78a4a747d6c4f0fff1jeonghoon.lim if (property_set("bluetooth.hciattach", "false") < 0) 2483a293d2850d4530054cdcc78a4a747d6c4f0fff1jeonghoon.lim#endif 2493a293d2850d4530054cdcc78a4a747d6c4f0fff1jeonghoon.lim { 2509657b13bd143660e9285e9bec379eec12c866110Steve Block ALOGE("Error stopping hciattach"); 2517342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 2527342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 2537342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2543a293d2850d4530054cdcc78a4a747d6c4f0fff1jeonghoon.lim#ifndef BLUETOOTH_DOES_NOT_USE_RFKILL 2557342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (set_bluetooth_power(0) < 0) { 2567342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 2577342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 2583a293d2850d4530054cdcc78a4a747d6c4f0fff1jeonghoon.lim#endif 2597342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ret = 0; 2607342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2617342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectout: 2627342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (hci_sock >= 0) close(hci_sock); 2637342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project return ret; 2647342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project} 2657342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2667342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectint bt_is_enabled() { 267c7be2810d52c07f8cff574c93166a02f3c14d878Steve Block ALOGV(__FUNCTION__); 2687342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2697342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int hci_sock = -1; 2707342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project int ret = -1; 2717342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project struct hci_dev_info dev_info; 2727342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2737342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2743a293d2850d4530054cdcc78a4a747d6c4f0fff1jeonghoon.lim#ifndef BLUETOOTH_DOES_NOT_USE_RFKILL 2757342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project // Check power first 2767342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ret = check_bluetooth_power(); 2777342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (ret == -1 || ret == 0) goto out; 2783a293d2850d4530054cdcc78a4a747d6c4f0fff1jeonghoon.lim#endif 2797342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2807342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ret = -1; 2817342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2827342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project // Power is on, now check if the HCI interface is up 2837342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project hci_sock = create_hci_sock(); 2847342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (hci_sock < 0) goto out; 2857342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2867342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project dev_info.dev_id = HCI_DEV_ID; 2877342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (ioctl(hci_sock, HCIGETDEVINFO, (void *)&dev_info) < 0) { 2887342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project ret = 0; 2897342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project goto out; 2907342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project } 2917342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2921890bf01833f6cab431f014af7a20fcbed3a4e13Jaikumar Ganesh if (dev_info.flags & (1 << (HCI_UP & 31))) { 2931890bf01833f6cab431f014af7a20fcbed3a4e13Jaikumar Ganesh ret = 1; 2941890bf01833f6cab431f014af7a20fcbed3a4e13Jaikumar Ganesh } else { 2951890bf01833f6cab431f014af7a20fcbed3a4e13Jaikumar Ganesh ret = 0; 2961890bf01833f6cab431f014af7a20fcbed3a4e13Jaikumar Ganesh } 2977342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project 2987342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Projectout: 2997342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project if (hci_sock >= 0) close(hci_sock); 3007342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project return ret; 3017342a3e6a751116a193ff27d69b87eda478a5016The Android Open Source Project} 302a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly 303a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pellyint ba2str(const bdaddr_t *ba, char *str) { 304a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly return sprintf(str, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", 305a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly ba->b[5], ba->b[4], ba->b[3], ba->b[2], ba->b[1], ba->b[0]); 306a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly} 307a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly 308a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pellyint str2ba(const char *str, bdaddr_t *ba) { 309a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly int i; 310a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly for (i = 5; i >= 0; i--) { 3116e6506eb74c918e761f9ba08a6c71897334747c1Glenn Kasten ba->b[i] = (uint8_t) strtoul(str, (char **) &str, 16); 312a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly str++; 313a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly } 314a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly return 0; 315a15c33f9aaf27f75a7f6fa02a539b54caace4d35Nick Pelly} 316