Home | History | Annotate | Download | only in bluetooth
      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 (at) 1.0.hikey"
     18 
     19 #include "bluetooth_hci.h"
     20 
     21 #include <android-base/logging.h>
     22 #include <sys/ioctl.h>
     23 #include <sys/socket.h>
     24 #include <unistd.h>
     25 #include <utils/Log.h>
     26 
     27 namespace android {
     28 namespace hardware {
     29 namespace bluetooth {
     30 namespace V1_0 {
     31 namespace hikey {
     32 
     33 using android::hardware::hidl_vec;
     34 
     35 BluetoothHci::BluetoothHci()
     36     : deathRecipient(new BluetoothDeathRecipient(this)) {}
     37 
     38 Return<void> BluetoothHci::initialize(
     39     const ::android::sp<IBluetoothHciCallbacks>& cb) {
     40   ALOGI("BluetoothHci::initialize()");
     41 
     42   hci_tty_fd_ = open("/dev/hci_tty", O_RDWR);
     43   if (hci_tty_fd_ < 0) {
     44     ALOGE("%s: Can't open hci_tty (%s)", __func__, strerror(errno));
     45     cb->initializationComplete(Status::INITIALIZATION_ERROR);
     46     return Void();
     47   }
     48 
     49   event_cb_ = cb;
     50   event_cb_->linkToDeath(deathRecipient, 0);
     51 
     52   hci_ = new hci::H4Protocol(
     53       hci_tty_fd_,
     54       [cb](const hidl_vec<uint8_t>& packet) { cb->hciEventReceived(packet); },
     55       [cb](const hidl_vec<uint8_t>& packet) { cb->aclDataReceived(packet); },
     56       [cb](const hidl_vec<uint8_t>& packet) { cb->scoDataReceived(packet); });
     57 
     58   // Use a socket pair to enforce the TI FIONREAD requirement.
     59   int sockfd[2];
     60   socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd);
     61   int shim_fd = sockfd[0];
     62   int for_hci = sockfd[1];
     63 
     64   fd_watcher_.WatchFdForNonBlockingReads(hci_tty_fd_, [this, shim_fd](int fd) {
     65     int tty_bytes = 0;
     66     if (TEMP_FAILURE_RETRY(ioctl(fd, FIONREAD, &tty_bytes)))
     67       ALOGE("%s:FIONREAD %s", __func__, strerror(errno));
     68     ALOGV("%s:tty_bytes = %d", __func__, tty_bytes);
     69 
     70     uint8_t* tmp_buffer = new uint8_t[tty_bytes];
     71     size_t bytes_read = TEMP_FAILURE_RETRY(read(fd, tmp_buffer, tty_bytes));
     72     CHECK(static_cast<int>(bytes_read) == tty_bytes);
     73     size_t bytes_written =
     74         TEMP_FAILURE_RETRY(write(shim_fd, tmp_buffer, tty_bytes));
     75     CHECK(static_cast<int>(bytes_written) == tty_bytes);
     76     delete[] tmp_buffer;
     77   });
     78 
     79   fd_watcher_.WatchFdForNonBlockingReads(
     80       for_hci, [this](int fd) { hci_->OnDataReady(fd); });
     81 
     82   cb->initializationComplete(Status::SUCCESS);
     83   return Void();
     84 }
     85 
     86 Return<void> BluetoothHci::close() {
     87   ALOGI("BluetoothHci::close()");
     88 
     89   if (hci_tty_fd_ >= 0) {
     90     fd_watcher_.StopWatchingFileDescriptors();
     91     ::close(hci_tty_fd_);
     92     hci_tty_fd_ = -1;
     93   }
     94 
     95   event_cb_->unlinkToDeath(deathRecipient);
     96 
     97   if (hci_ != nullptr) {
     98     delete hci_;
     99     hci_ = nullptr;
    100   }
    101 
    102   return Void();
    103 }
    104 
    105 Return<void> BluetoothHci::sendHciCommand(const hidl_vec<uint8_t>& packet) {
    106   hci_->Send(HCI_PACKET_TYPE_COMMAND, packet.data(), packet.size());
    107   return Void();
    108 }
    109 
    110 Return<void> BluetoothHci::sendAclData(const hidl_vec<uint8_t>& packet) {
    111   hci_->Send(HCI_PACKET_TYPE_ACL_DATA, packet.data(), packet.size());
    112   return Void();
    113 }
    114 
    115 Return<void> BluetoothHci::sendScoData(const hidl_vec<uint8_t>& packet) {
    116   hci_->Send(HCI_PACKET_TYPE_SCO_DATA, packet.data(), packet.size());
    117   return Void();
    118 }
    119 
    120 }  // namespace hikey
    121 }  // namespace V1_0
    122 }  // namespace bluetooth
    123 }  // namespace hardware
    124 }  // namespace android
    125