Home | History | Annotate | Download | only in interface
      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-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 
     47 struct sockaddr_hci {
     48     sa_family_t hci_family;
     49     unsigned short hci_dev;
     50     unsigned short hci_channel;
     51 };
     52 
     53 struct 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 
     60 struct 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 
     67 namespace android {
     68 namespace hardware {
     69 namespace bluetooth {
     70 namespace V1_0 {
     71 namespace btlinux {
     72 
     73 int 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 
    107 void 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 
    116 int 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 
    194 end:
    195   ::close(fd);
    196   return ret;
    197 }
    198 
    199 int 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 
    224 int 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 
    245 class 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 
    264 BluetoothHci::BluetoothHci()
    265     : death_recipient_(new BluetoothDeathRecipient(this)) {}
    266 
    267 Return<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 
    303 Return<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 
    316 Return<void> BluetoothHci::sendHciCommand(const hidl_vec<uint8_t>& command) {
    317   sendDataToController(HCI_DATA_TYPE_COMMAND, command);
    318   return Void();
    319 }
    320 
    321 Return<void> BluetoothHci::sendAclData(const hidl_vec<uint8_t>& data) {
    322   sendDataToController(HCI_DATA_TYPE_ACL, data);
    323   return Void();
    324 }
    325 
    326 Return<void> BluetoothHci::sendScoData(const hidl_vec<uint8_t>& data) {
    327   sendDataToController(HCI_DATA_TYPE_SCO, data);
    328   return Void();
    329 }
    330 
    331 void BluetoothHci::sendDataToController(const uint8_t type,
    332                                         const hidl_vec<uint8_t>& data) {
    333   hci_handle_->Send(type, data.data(), data.size());
    334 }
    335 
    336 IBluetoothHci* 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