Home | History | Annotate | Download | only in src
      1 /******************************************************************************
      2  *
      3  *  Copyright 2017 Google, Inc.
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 #define LOG_TAG "bt_hci"
     20 
     21 #include "hci_layer.h"
     22 
     23 #include <fcntl.h>
     24 #include <sys/stat.h>
     25 #include <sys/types.h>
     26 
     27 #include <base/location.h>
     28 #include <base/logging.h>
     29 #include "buffer_allocator.h"
     30 #include "osi/include/log.h"
     31 
     32 #include <android/hardware/bluetooth/1.0/IBluetoothHci.h>
     33 #include <android/hardware/bluetooth/1.0/IBluetoothHciCallbacks.h>
     34 #include <android/hardware/bluetooth/1.0/types.h>
     35 #include <hwbinder/ProcessState.h>
     36 
     37 #define LOG_PATH "/data/misc/bluetooth/logs/firmware_events.log"
     38 #define LAST_LOG_PATH "/data/misc/bluetooth/logs/firmware_events.log.last"
     39 
     40 using android::hardware::bluetooth::V1_0::IBluetoothHci;
     41 using android::hardware::bluetooth::V1_0::IBluetoothHciCallbacks;
     42 using android::hardware::bluetooth::V1_0::HciPacket;
     43 using android::hardware::bluetooth::V1_0::Status;
     44 using android::hardware::ProcessState;
     45 using ::android::hardware::Return;
     46 using ::android::hardware::Void;
     47 using ::android::hardware::hidl_vec;
     48 
     49 extern void initialization_complete();
     50 extern void hci_event_received(const tracked_objects::Location& from_here,
     51                                BT_HDR* packet);
     52 extern void acl_event_received(BT_HDR* packet);
     53 extern void sco_data_received(BT_HDR* packet);
     54 
     55 android::sp<IBluetoothHci> btHci;
     56 
     57 class BluetoothHciCallbacks : public IBluetoothHciCallbacks {
     58  public:
     59   BluetoothHciCallbacks() {
     60     buffer_allocator = buffer_allocator_get_interface();
     61   }
     62 
     63   BT_HDR* WrapPacketAndCopy(uint16_t event, const hidl_vec<uint8_t>& data) {
     64     size_t packet_size = data.size() + BT_HDR_SIZE;
     65     BT_HDR* packet =
     66         reinterpret_cast<BT_HDR*>(buffer_allocator->alloc(packet_size));
     67     packet->offset = 0;
     68     packet->len = data.size();
     69     packet->layer_specific = 0;
     70     packet->event = event;
     71     // TODO(eisenbach): Avoid copy here; if BT_HDR->data can be ensured to
     72     // be the only way the data is accessed, a pointer could be passed here...
     73     memcpy(packet->data, data.data(), data.size());
     74     return packet;
     75   }
     76 
     77   Return<void> initializationComplete(Status status) {
     78     CHECK(status == Status::SUCCESS);
     79     initialization_complete();
     80     return Void();
     81   }
     82 
     83   Return<void> hciEventReceived(const hidl_vec<uint8_t>& event) {
     84     BT_HDR* packet = WrapPacketAndCopy(MSG_HC_TO_STACK_HCI_EVT, event);
     85     hci_event_received(FROM_HERE, packet);
     86     return Void();
     87   }
     88 
     89   Return<void> aclDataReceived(const hidl_vec<uint8_t>& data) {
     90     BT_HDR* packet = WrapPacketAndCopy(MSG_HC_TO_STACK_HCI_ACL, data);
     91     acl_event_received(packet);
     92     return Void();
     93   }
     94 
     95   Return<void> scoDataReceived(const hidl_vec<uint8_t>& data) {
     96     BT_HDR* packet = WrapPacketAndCopy(MSG_HC_TO_STACK_HCI_SCO, data);
     97     sco_data_received(packet);
     98     return Void();
     99   }
    100 
    101   const allocator_t* buffer_allocator;
    102 };
    103 
    104 void hci_initialize() {
    105   LOG_INFO(LOG_TAG, "%s", __func__);
    106 
    107   btHci = IBluetoothHci::getService();
    108   // If android.hardware.bluetooth* is not found, Bluetooth can not continue.
    109   CHECK(btHci != nullptr);
    110   LOG_INFO(LOG_TAG, "%s: IBluetoothHci::getService() returned %p (%s)",
    111            __func__, btHci.get(), (btHci->isRemote() ? "remote" : "local"));
    112 
    113   // Block allows allocation of a variable that might be bypassed by goto.
    114   {
    115     android::sp<IBluetoothHciCallbacks> callbacks = new BluetoothHciCallbacks();
    116     btHci->initialize(callbacks);
    117   }
    118 }
    119 
    120 void hci_close() {
    121   btHci->close();
    122   btHci = nullptr;
    123 }
    124 
    125 void hci_transmit(BT_HDR* packet) {
    126   HciPacket data;
    127   data.setToExternal(packet->data + packet->offset, packet->len);
    128 
    129   uint16_t event = packet->event & MSG_EVT_MASK;
    130   switch (event & MSG_EVT_MASK) {
    131     case MSG_STACK_TO_HC_HCI_CMD:
    132       btHci->sendHciCommand(data);
    133       break;
    134     case MSG_STACK_TO_HC_HCI_ACL:
    135       btHci->sendAclData(data);
    136       break;
    137     case MSG_STACK_TO_HC_HCI_SCO:
    138       btHci->sendScoData(data);
    139       break;
    140     default:
    141       LOG_ERROR(LOG_TAG, "Unknown packet type (%d)", event);
    142       break;
    143   }
    144 }
    145 
    146 int hci_open_firmware_log_file() {
    147   if (rename(LOG_PATH, LAST_LOG_PATH) == -1 && errno != ENOENT) {
    148     LOG_ERROR(LOG_TAG, "%s unable to rename '%s' to '%s': %s", __func__,
    149               LOG_PATH, LAST_LOG_PATH, strerror(errno));
    150   }
    151 
    152   mode_t prevmask = umask(0);
    153   int logfile_fd = open(LOG_PATH, O_WRONLY | O_CREAT | O_TRUNC,
    154                         S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
    155   umask(prevmask);
    156   if (logfile_fd == INVALID_FD) {
    157     LOG_ERROR(LOG_TAG, "%s unable to open '%s': %s", __func__, LOG_PATH,
    158               strerror(errno));
    159   }
    160 
    161   return logfile_fd;
    162 }
    163 
    164 void hci_close_firmware_log_file(int fd) {
    165   if (fd != INVALID_FD) close(fd);
    166 }
    167 
    168 void hci_log_firmware_debug_packet(int fd, BT_HDR* packet) {
    169   TEMP_FAILURE_RETRY(write(fd, packet->data, packet->len));
    170 }
    171