Home | History | Annotate | Download | only in default
      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 #include "vendor_interface.h"
     18 
     19 #define LOG_TAG "android.hardware.bluetooth (at) 1.0-impl"
     20 #include <cutils/properties.h>
     21 #include <utils/Log.h>
     22 
     23 #include <dlfcn.h>
     24 #include <fcntl.h>
     25 
     26 #include "bluetooth_address.h"
     27 #include "h4_protocol.h"
     28 #include "mct_protocol.h"
     29 
     30 static const char* VENDOR_LIBRARY_NAME = "libbt-vendor.so";
     31 static const char* VENDOR_LIBRARY_SYMBOL_NAME =
     32     "BLUETOOTH_VENDOR_LIB_INTERFACE";
     33 
     34 static const int INVALID_FD = -1;
     35 
     36 namespace {
     37 
     38 using android::hardware::bluetooth::V1_0::implementation::VendorInterface;
     39 using android::hardware::hidl_vec;
     40 
     41 struct {
     42   tINT_CMD_CBACK cb;
     43   uint16_t opcode;
     44 } internal_command;
     45 
     46 // True when LPM is not enabled yet or wake is not asserted.
     47 bool lpm_wake_deasserted;
     48 uint32_t lpm_timeout_ms;
     49 bool recent_activity_flag;
     50 
     51 VendorInterface* g_vendor_interface = nullptr;
     52 std::mutex wakeup_mutex_;
     53 
     54 HC_BT_HDR* WrapPacketAndCopy(uint16_t event, const hidl_vec<uint8_t>& data) {
     55   size_t packet_size = data.size() + sizeof(HC_BT_HDR);
     56   HC_BT_HDR* packet = reinterpret_cast<HC_BT_HDR*>(new uint8_t[packet_size]);
     57   packet->offset = 0;
     58   packet->len = data.size();
     59   packet->layer_specific = 0;
     60   packet->event = event;
     61   // TODO(eisenbach): Avoid copy here; if BT_HDR->data can be ensured to
     62   // be the only way the data is accessed, a pointer could be passed here...
     63   memcpy(packet->data, data.data(), data.size());
     64   return packet;
     65 }
     66 
     67 bool internal_command_event_match(const hidl_vec<uint8_t>& packet) {
     68   uint8_t event_code = packet[0];
     69   if (event_code != HCI_COMMAND_COMPLETE_EVENT) {
     70     ALOGE("%s: Unhandled event type %02X", __func__, event_code);
     71     return false;
     72   }
     73 
     74   size_t opcode_offset = HCI_EVENT_PREAMBLE_SIZE + 1;  // Skip num packets.
     75 
     76   uint16_t opcode = packet[opcode_offset] | (packet[opcode_offset + 1] << 8);
     77 
     78   ALOGV("%s internal_command.opcode = %04X opcode = %04x", __func__,
     79         internal_command.opcode, opcode);
     80   return opcode == internal_command.opcode;
     81 }
     82 
     83 uint8_t transmit_cb(uint16_t opcode, void* buffer, tINT_CMD_CBACK callback) {
     84   ALOGV("%s opcode: 0x%04x, ptr: %p, cb: %p", __func__, opcode, buffer,
     85         callback);
     86   internal_command.cb = callback;
     87   internal_command.opcode = opcode;
     88   uint8_t type = HCI_PACKET_TYPE_COMMAND;
     89   HC_BT_HDR* bt_hdr = reinterpret_cast<HC_BT_HDR*>(buffer);
     90   VendorInterface::get()->Send(type, bt_hdr->data, bt_hdr->len);
     91   delete[] reinterpret_cast<uint8_t*>(buffer);
     92   return true;
     93 }
     94 
     95 void firmware_config_cb(bt_vendor_op_result_t result) {
     96   ALOGV("%s result: %d", __func__, result);
     97   VendorInterface::get()->OnFirmwareConfigured(result);
     98 }
     99 
    100 void sco_config_cb(bt_vendor_op_result_t result) {
    101   ALOGD("%s result: %d", __func__, result);
    102 }
    103 
    104 void low_power_mode_cb(bt_vendor_op_result_t result) {
    105   ALOGD("%s result: %d", __func__, result);
    106 }
    107 
    108 void sco_audiostate_cb(bt_vendor_op_result_t result) {
    109   ALOGD("%s result: %d", __func__, result);
    110 }
    111 
    112 void* buffer_alloc_cb(int size) {
    113   void* p = new uint8_t[size];
    114   ALOGV("%s pts: %p, size: %d", __func__, p, size);
    115   return p;
    116 }
    117 
    118 void buffer_free_cb(void* buffer) {
    119   ALOGV("%s ptr: %p", __func__, buffer);
    120   delete[] reinterpret_cast<uint8_t*>(buffer);
    121 }
    122 
    123 void epilog_cb(bt_vendor_op_result_t result) {
    124   ALOGD("%s result: %d", __func__, result);
    125 }
    126 
    127 void a2dp_offload_cb(bt_vendor_op_result_t result, bt_vendor_opcode_t op,
    128                      uint8_t av_handle) {
    129   ALOGD("%s result: %d, op: %d, handle: %d", __func__, result, op, av_handle);
    130 }
    131 
    132 const bt_vendor_callbacks_t lib_callbacks = {
    133     sizeof(lib_callbacks), firmware_config_cb, sco_config_cb,
    134     low_power_mode_cb,     sco_audiostate_cb,  buffer_alloc_cb,
    135     buffer_free_cb,        transmit_cb,        epilog_cb,
    136     a2dp_offload_cb};
    137 
    138 }  // namespace
    139 
    140 namespace android {
    141 namespace hardware {
    142 namespace bluetooth {
    143 namespace V1_0 {
    144 namespace implementation {
    145 
    146 class FirmwareStartupTimer {
    147  public:
    148   FirmwareStartupTimer() : start_time_(std::chrono::steady_clock::now()) {}
    149 
    150   ~FirmwareStartupTimer() {
    151     std::chrono::duration<double> duration =
    152         std::chrono::steady_clock::now() - start_time_;
    153     double s = duration.count();
    154     if (s == 0) return;
    155     ALOGI("Firmware configured in %.3fs", s);
    156   }
    157 
    158  private:
    159   std::chrono::steady_clock::time_point start_time_;
    160 };
    161 
    162 bool VendorInterface::Initialize(
    163     InitializeCompleteCallback initialize_complete_cb,
    164     PacketReadCallback event_cb, PacketReadCallback acl_cb,
    165     PacketReadCallback sco_cb) {
    166   if (g_vendor_interface) {
    167     ALOGE("%s: No previous Shutdown()?", __func__);
    168     return false;
    169   }
    170   g_vendor_interface = new VendorInterface();
    171   return g_vendor_interface->Open(initialize_complete_cb, event_cb, acl_cb,
    172                                   sco_cb);
    173 }
    174 
    175 void VendorInterface::Shutdown() {
    176   LOG_ALWAYS_FATAL_IF(!g_vendor_interface, "%s: No Vendor interface!",
    177                       __func__);
    178   g_vendor_interface->Close();
    179   delete g_vendor_interface;
    180   g_vendor_interface = nullptr;
    181 }
    182 
    183 VendorInterface* VendorInterface::get() { return g_vendor_interface; }
    184 
    185 bool VendorInterface::Open(InitializeCompleteCallback initialize_complete_cb,
    186                            PacketReadCallback event_cb,
    187                            PacketReadCallback acl_cb,
    188                            PacketReadCallback sco_cb) {
    189   initialize_complete_cb_ = initialize_complete_cb;
    190 
    191   // Initialize vendor interface
    192 
    193   lib_handle_ = dlopen(VENDOR_LIBRARY_NAME, RTLD_NOW);
    194   if (!lib_handle_) {
    195     ALOGE("%s unable to open %s (%s)", __func__, VENDOR_LIBRARY_NAME,
    196           dlerror());
    197     return false;
    198   }
    199 
    200   lib_interface_ = reinterpret_cast<bt_vendor_interface_t*>(
    201       dlsym(lib_handle_, VENDOR_LIBRARY_SYMBOL_NAME));
    202   if (!lib_interface_) {
    203     ALOGE("%s unable to find symbol %s in %s (%s)", __func__,
    204           VENDOR_LIBRARY_SYMBOL_NAME, VENDOR_LIBRARY_NAME, dlerror());
    205     return false;
    206   }
    207 
    208   // Get the local BD address
    209 
    210   uint8_t local_bda[BluetoothAddress::kBytes];
    211   if (!BluetoothAddress::get_local_address(local_bda)) {
    212     LOG_ALWAYS_FATAL("%s: No Bluetooth Address!", __func__);
    213   }
    214   int status = lib_interface_->init(&lib_callbacks, (unsigned char*)local_bda);
    215   if (status) {
    216     ALOGE("%s unable to initialize vendor library: %d", __func__, status);
    217     return false;
    218   }
    219 
    220   ALOGD("%s vendor library loaded", __func__);
    221 
    222   // Power on the controller
    223 
    224   int power_state = BT_VND_PWR_ON;
    225   lib_interface_->op(BT_VND_OP_POWER_CTRL, &power_state);
    226 
    227   // Get the UART socket(s)
    228 
    229   int fd_list[CH_MAX] = {0};
    230   int fd_count = lib_interface_->op(BT_VND_OP_USERIAL_OPEN, &fd_list);
    231 
    232   if (fd_count < 1 || fd_count > CH_MAX - 1) {
    233     ALOGE("%s: fd_count %d is invalid!", __func__, fd_count);
    234     return false;
    235   }
    236 
    237   for (int i = 0; i < fd_count; i++) {
    238     if (fd_list[i] == INVALID_FD) {
    239       ALOGE("%s: fd %d is invalid!", __func__, fd_list[i]);
    240       return false;
    241     }
    242   }
    243 
    244   event_cb_ = event_cb;
    245   PacketReadCallback intercept_events = [this](const hidl_vec<uint8_t>& event) {
    246     HandleIncomingEvent(event);
    247   };
    248 
    249   if (fd_count == 1) {
    250     hci::H4Protocol* h4_hci =
    251         new hci::H4Protocol(fd_list[0], intercept_events, acl_cb, sco_cb);
    252     fd_watcher_.WatchFdForNonBlockingReads(
    253         fd_list[0], [h4_hci](int fd) { h4_hci->OnDataReady(fd); });
    254     hci_ = h4_hci;
    255   } else {
    256     hci::MctProtocol* mct_hci =
    257         new hci::MctProtocol(fd_list, intercept_events, acl_cb);
    258     fd_watcher_.WatchFdForNonBlockingReads(
    259         fd_list[CH_EVT], [mct_hci](int fd) { mct_hci->OnEventDataReady(fd); });
    260     fd_watcher_.WatchFdForNonBlockingReads(
    261         fd_list[CH_ACL_IN],
    262         [mct_hci](int fd) { mct_hci->OnAclDataReady(fd); });
    263     hci_ = mct_hci;
    264   }
    265 
    266   // Initially, the power management is off.
    267   lpm_wake_deasserted = true;
    268 
    269   // Start configuring the firmware
    270   firmware_startup_timer_ = new FirmwareStartupTimer();
    271   lib_interface_->op(BT_VND_OP_FW_CFG, nullptr);
    272 
    273   return true;
    274 }
    275 
    276 void VendorInterface::Close() {
    277   // These callbacks may send HCI events (vendor-dependent), so make sure to
    278   // StopWatching the file descriptor after this.
    279   if (lib_interface_ != nullptr) {
    280     bt_vendor_lpm_mode_t mode = BT_VND_LPM_DISABLE;
    281     lib_interface_->op(BT_VND_OP_LPM_SET_MODE, &mode);
    282   }
    283 
    284   fd_watcher_.StopWatchingFileDescriptors();
    285 
    286   if (hci_ != nullptr) {
    287     delete hci_;
    288     hci_ = nullptr;
    289   }
    290 
    291   if (lib_interface_ != nullptr) {
    292     lib_interface_->op(BT_VND_OP_USERIAL_CLOSE, nullptr);
    293 
    294     int power_state = BT_VND_PWR_OFF;
    295     lib_interface_->op(BT_VND_OP_POWER_CTRL, &power_state);
    296 
    297     lib_interface_->cleanup();
    298   }
    299 
    300   if (lib_handle_ != nullptr) {
    301     dlclose(lib_handle_);
    302     lib_handle_ = nullptr;
    303   }
    304 
    305   if (firmware_startup_timer_ != nullptr) {
    306     delete firmware_startup_timer_;
    307     firmware_startup_timer_ = nullptr;
    308   }
    309 }
    310 
    311 size_t VendorInterface::Send(uint8_t type, const uint8_t* data, size_t length) {
    312   std::unique_lock<std::mutex> lock(wakeup_mutex_);
    313   recent_activity_flag = true;
    314 
    315   if (lpm_wake_deasserted == true) {
    316     // Restart the timer.
    317     fd_watcher_.ConfigureTimeout(std::chrono::milliseconds(lpm_timeout_ms),
    318                                  [this]() { OnTimeout(); });
    319     // Assert wake.
    320     lpm_wake_deasserted = false;
    321     bt_vendor_lpm_wake_state_t wakeState = BT_VND_LPM_WAKE_ASSERT;
    322     lib_interface_->op(BT_VND_OP_LPM_WAKE_SET_STATE, &wakeState);
    323     ALOGV("%s: Sent wake before (%02x)", __func__, data[0] | (data[1] << 8));
    324   }
    325 
    326   return hci_->Send(type, data, length);
    327 }
    328 
    329 void VendorInterface::OnFirmwareConfigured(uint8_t result) {
    330   ALOGD("%s result: %d", __func__, result);
    331 
    332   if (firmware_startup_timer_ != nullptr) {
    333     delete firmware_startup_timer_;
    334     firmware_startup_timer_ = nullptr;
    335   }
    336 
    337   if (initialize_complete_cb_ != nullptr) {
    338     initialize_complete_cb_(result == 0);
    339     initialize_complete_cb_ = nullptr;
    340   }
    341 
    342   lib_interface_->op(BT_VND_OP_GET_LPM_IDLE_TIMEOUT, &lpm_timeout_ms);
    343   ALOGI("%s: lpm_timeout_ms %d", __func__, lpm_timeout_ms);
    344 
    345   bt_vendor_lpm_mode_t mode = BT_VND_LPM_ENABLE;
    346   lib_interface_->op(BT_VND_OP_LPM_SET_MODE, &mode);
    347 
    348   ALOGD("%s Calling StartLowPowerWatchdog()", __func__);
    349   fd_watcher_.ConfigureTimeout(std::chrono::milliseconds(lpm_timeout_ms),
    350                                [this]() { OnTimeout(); });
    351 }
    352 
    353 void VendorInterface::OnTimeout() {
    354   ALOGV("%s", __func__);
    355   std::unique_lock<std::mutex> lock(wakeup_mutex_);
    356   if (recent_activity_flag == false) {
    357     lpm_wake_deasserted = true;
    358     bt_vendor_lpm_wake_state_t wakeState = BT_VND_LPM_WAKE_DEASSERT;
    359     lib_interface_->op(BT_VND_OP_LPM_WAKE_SET_STATE, &wakeState);
    360     fd_watcher_.ConfigureTimeout(std::chrono::seconds(0), []() {
    361       ALOGE("Zero timeout! Should never happen.");
    362     });
    363   }
    364   recent_activity_flag = false;
    365 }
    366 
    367 void VendorInterface::HandleIncomingEvent(const hidl_vec<uint8_t>& hci_packet) {
    368   if (internal_command.cb != nullptr &&
    369       internal_command_event_match(hci_packet)) {
    370     HC_BT_HDR* bt_hdr = WrapPacketAndCopy(HCI_PACKET_TYPE_EVENT, hci_packet);
    371 
    372     // The callbacks can send new commands, so don't zero after calling.
    373     tINT_CMD_CBACK saved_cb = internal_command.cb;
    374     internal_command.cb = nullptr;
    375     saved_cb(bt_hdr);
    376   } else {
    377     event_cb_(hci_packet);
    378   }
    379 }
    380 
    381 }  // namespace implementation
    382 }  // namespace V1_0
    383 }  // namespace bluetooth
    384 }  // namespace hardware
    385 }  // namespace android
    386