1//
2// Copyright 2016 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17#define LOG_TAG "android.hardware.bluetooth@1.0-btlinux"
18#include <errno.h>
19#include <fcntl.h>
20#include <poll.h>
21#include <stdint.h>
22#include <stdlib.h>
23#include <string.h>
24
25#include <sys/socket.h>
26
27#include <utils/Log.h>
28
29#include "bluetooth_hci.h"
30
31#define BTPROTO_HCI 1
32
33#define HCI_CHANNEL_USER 1
34#define HCI_CHANNEL_CONTROL 3
35#define HCI_DEV_NONE 0xffff
36
37/* reference from <kernel>/include/net/bluetooth/mgmt.h */
38#define MGMT_OP_INDEX_LIST 0x0003
39#define MGMT_EV_INDEX_ADDED 0x0004
40#define MGMT_EV_COMMAND_COMP 0x0001
41#define MGMT_EV_SIZE_MAX 1024
42#define MGMT_EV_POLL_TIMEOUT 3000 /* 3000ms */
43#define WRITE_NO_INTR(fn) \
44  do {                  \
45  } while ((fn) == -1 && errno == EINTR)
46
47struct sockaddr_hci {
48    sa_family_t hci_family;
49    unsigned short hci_dev;
50    unsigned short hci_channel;
51};
52
53struct mgmt_pkt {
54    uint16_t opcode;
55    uint16_t index;
56    uint16_t len;
57    uint8_t data[MGMT_EV_SIZE_MAX];
58} __attribute__((packed));
59
60struct mgmt_event_read_index {
61    uint16_t cc_opcode;
62    uint8_t status;
63    uint16_t num_intf;
64    uint16_t index[0];
65  } __attribute__((packed));
66
67namespace android {
68namespace hardware {
69namespace bluetooth {
70namespace V1_0 {
71namespace btlinux {
72
73int BluetoothHci::openBtHci() {
74
75  ALOGI( "%s", __func__);
76
77  int hci_interface = 0;
78  rfkill_state_ = NULL;
79  rfKill(1);
80
81  int fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
82  if (fd < 0) {
83    ALOGE( "Bluetooth socket error: %s", strerror(errno));
84    return -1;
85  }
86  bt_soc_fd_ = fd;
87
88  if (waitHciDev(hci_interface)) {
89    ALOGE( "HCI interface (%d) not found", hci_interface);
90    ::close(fd);
91    return -1;
92  }
93  struct sockaddr_hci addr;
94  memset(&addr, 0, sizeof(addr));
95  addr.hci_family = AF_BLUETOOTH;
96  addr.hci_dev = hci_interface;
97  addr.hci_channel = HCI_CHANNEL_USER;
98  if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
99    ALOGE( "HCI Channel Control: %s", strerror(errno));
100    ::close(fd);
101    return -1;
102  }
103  ALOGI( "HCI device ready");
104  return fd;
105}
106
107void BluetoothHci::closeBtHci() {
108  if (bt_soc_fd_ != -1) {
109    ::close(bt_soc_fd_);
110    bt_soc_fd_ = -1;
111  }
112  rfKill(0);
113  free(rfkill_state_);
114}
115
116int BluetoothHci::waitHciDev(int hci_interface) {
117  struct sockaddr_hci addr;
118  struct pollfd fds[1];
119  struct mgmt_pkt ev;
120  int fd;
121  int ret = 0;
122
123  ALOGI( "%s", __func__);
124  fd = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
125  if (fd < 0) {
126    ALOGE( "Bluetooth socket error: %s", strerror(errno));
127    return -1;
128  }
129  memset(&addr, 0, sizeof(addr));
130  addr.hci_family = AF_BLUETOOTH;
131  addr.hci_dev = HCI_DEV_NONE;
132  addr.hci_channel = HCI_CHANNEL_CONTROL;
133  if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
134    ALOGE( "HCI Channel Control: %s", strerror(errno));
135    ret = -1;
136    goto end;
137  }
138
139  fds[0].fd = fd;
140  fds[0].events = POLLIN;
141
142  /* Read Controller Index List Command */
143  ev.opcode = MGMT_OP_INDEX_LIST;
144  ev.index = HCI_DEV_NONE;
145  ev.len = 0;
146
147  ssize_t wrote;
148  WRITE_NO_INTR(wrote = write(fd, &ev, 6));
149  if (wrote != 6) {
150    ALOGE( "Unable to write mgmt command: %s", strerror(errno));
151    ret = -1;
152    goto end;
153  }
154  /* validate mentioned hci interface is present and registered with sock system */
155  while (1) {
156    int n;
157    WRITE_NO_INTR(n = poll(fds, 1, MGMT_EV_POLL_TIMEOUT));
158    if (n == -1) {
159      ALOGE( "Poll error: %s", strerror(errno));
160      ret = -1;
161      break;
162    } else if (n == 0) {
163      ALOGE( "Timeout, no HCI device detected");
164      ret = -1;
165      break;
166    }
167
168    if (fds[0].revents & POLLIN) {
169      WRITE_NO_INTR(n = read(fd, &ev, sizeof(struct mgmt_pkt)));
170      if (n < 0) {
171        ALOGE( "Error reading control channel: %s",
172                  strerror(errno));
173        ret = -1;
174        break;
175      }
176
177      if (ev.opcode == MGMT_EV_INDEX_ADDED && ev.index == hci_interface) {
178        goto end;
179      } else if (ev.opcode == MGMT_EV_COMMAND_COMP) {
180        struct mgmt_event_read_index* cc;
181        int i;
182
183        cc = (struct mgmt_event_read_index*)ev.data;
184
185        if (cc->cc_opcode != MGMT_OP_INDEX_LIST || cc->status != 0) continue;
186
187        for (i = 0; i < cc->num_intf; i++) {
188          if (cc->index[i] == hci_interface) goto end;
189        }
190      }
191    }
192  }
193
194end:
195  ::close(fd);
196  return ret;
197}
198
199int BluetoothHci::findRfKill() {
200    char rfkill_type[64];
201    char type[16];
202    int fd, size, i;
203    for(i = 0; rfkill_state_ == NULL; i++)
204    {
205        snprintf(rfkill_type, sizeof(rfkill_type), "/sys/class/rfkill/rfkill%d/type", i);
206        if ((fd = open(rfkill_type, O_RDONLY)) < 0)
207        {
208            ALOGE("open(%s) failed: %s (%d)\n", rfkill_type, strerror(errno), errno);
209            return -1;
210        }
211
212        size = read(fd, &type, sizeof(type));
213        ::close(fd);
214
215        if ((size >= 9) && !memcmp(type, "bluetooth", 9))
216        {
217            ::asprintf(&rfkill_state_, "/sys/class/rfkill/rfkill%d/state", i);
218            break;
219        }
220    }
221    return 0;
222}
223
224int BluetoothHci::rfKill(int block) {
225  int fd;
226  char on = (block)?'1':'0';
227  if (findRfKill() != 0) return 0;
228
229  fd = open(rfkill_state_, O_WRONLY);
230  if (fd < 0) {
231    ALOGE( "Unable to open /dev/rfkill");
232    return -1;
233  }
234  ssize_t len;
235  WRITE_NO_INTR(len = write(fd, &on, 1));
236  if (len < 0) {
237    ALOGE( "Failed to change rfkill state");
238    ::close(fd);
239    return -1;
240  }
241  ::close(fd);
242  return 0;
243}
244
245class BluetoothDeathRecipient : public hidl_death_recipient {
246 public:
247  BluetoothDeathRecipient(const sp<IBluetoothHci> hci) : mHci(hci) {}
248
249  virtual void serviceDied(
250      uint64_t /*cookie*/,
251      const wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
252    ALOGE("BluetoothDeathRecipient::serviceDied - Bluetooth service died");
253    has_died_ = true;
254    mHci->close();
255  }
256  sp<IBluetoothHci> mHci;
257  bool getHasDied() const { return has_died_; }
258  void setHasDied(bool has_died) { has_died_ = has_died; }
259
260 private:
261  bool has_died_;
262};
263
264BluetoothHci::BluetoothHci()
265    : death_recipient_(new BluetoothDeathRecipient(this)) {}
266
267Return<void> BluetoothHci::initialize(
268    const ::android::sp<IBluetoothHciCallbacks>& cb) {
269  ALOGI("BluetoothHci::initialize()");
270  if (cb == nullptr) {
271    ALOGE("cb == nullptr! -> Unable to call initializationComplete(ERR)");
272    return Void();
273  }
274
275  death_recipient_->setHasDied(false);
276  cb->linkToDeath(death_recipient_, 0);
277  int hci_fd = openBtHci();
278  auto hidl_status = cb->initializationComplete(
279          hci_fd > 0 ? Status::SUCCESS : Status::INITIALIZATION_ERROR);
280  if (!hidl_status.isOk()) {
281      ALOGE("VendorInterface -> Unable to call initializationComplete(ERR)");
282  }
283  hci::H4Protocol* h4_hci = new hci::H4Protocol(
284      hci_fd,
285      [cb](const hidl_vec<uint8_t>& packet) { cb->hciEventReceived(packet); },
286      [cb](const hidl_vec<uint8_t>& packet) { cb->aclDataReceived(packet); },
287      [cb](const hidl_vec<uint8_t>& packet) { cb->scoDataReceived(packet); });
288
289  fd_watcher_.WatchFdForNonBlockingReads(
290          hci_fd, [h4_hci](int fd) { h4_hci->OnDataReady(fd); });
291  hci_handle_ = h4_hci;
292
293  unlink_cb_ = [cb](sp<BluetoothDeathRecipient>& death_recipient) {
294    if (death_recipient->getHasDied())
295      ALOGI("Skipping unlink call, service died.");
296    else
297      cb->unlinkToDeath(death_recipient);
298  };
299
300  return Void();
301}
302
303Return<void> BluetoothHci::close() {
304  ALOGI("BluetoothHci::close()");
305  unlink_cb_(death_recipient_);
306  fd_watcher_.StopWatchingFileDescriptors();
307
308  if (hci_handle_ != nullptr) {
309    delete hci_handle_;
310    hci_handle_ = nullptr;
311  }
312  closeBtHci();
313  return Void();
314}
315
316Return<void> BluetoothHci::sendHciCommand(const hidl_vec<uint8_t>& command) {
317  sendDataToController(HCI_DATA_TYPE_COMMAND, command);
318  return Void();
319}
320
321Return<void> BluetoothHci::sendAclData(const hidl_vec<uint8_t>& data) {
322  sendDataToController(HCI_DATA_TYPE_ACL, data);
323  return Void();
324}
325
326Return<void> BluetoothHci::sendScoData(const hidl_vec<uint8_t>& data) {
327  sendDataToController(HCI_DATA_TYPE_SCO, data);
328  return Void();
329}
330
331void BluetoothHci::sendDataToController(const uint8_t type,
332                                        const hidl_vec<uint8_t>& data) {
333  hci_handle_->Send(type, data.data(), data.size());
334}
335
336IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* /* name */) {
337  return new BluetoothHci();
338}
339
340}  // namespace btlinux
341}  // namespace V1_0
342}  // namespace bluetooth
343}  // namespace hardware
344}  // namespace android
345