189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach//
289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach// Copyright 2016 The Android Open Source Project
389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach//
489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach// Licensed under the Apache License, Version 2.0 (the "License");
589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach// you may not use this file except in compliance with the License.
689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach// You may obtain a copy of the License at
789ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach//
889ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach// http://www.apache.org/licenses/LICENSE-2.0
989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach//
1089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach// Unless required by applicable law or agreed to in writing, software
1189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach// distributed under the License is distributed on an "AS IS" BASIS,
1289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach// See the License for the specific language governing permissions and
1489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach// limitations under the License.
1589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach//
1689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
1789ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach#include "vendor_interface.h"
1889ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
1989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach#define LOG_TAG "android.hardware.bluetooth@1.0-impl"
206a7d62226403d8081fbe22dbb3c41af4684fe0e4Myles Watson#include <cutils/properties.h>
2189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach#include <utils/Log.h>
2289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
2389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach#include <dlfcn.h>
246a7d62226403d8081fbe22dbb3c41af4684fe0e4Myles Watson#include <fcntl.h>
256a7d62226403d8081fbe22dbb3c41af4684fe0e4Myles Watson
266a7d62226403d8081fbe22dbb3c41af4684fe0e4Myles Watson#include "bluetooth_address.h"
27917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson#include "h4_protocol.h"
28917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson#include "mct_protocol.h"
2989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
3089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachstatic const char* VENDOR_LIBRARY_NAME = "libbt-vendor.so";
3189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachstatic const char* VENDOR_LIBRARY_SYMBOL_NAME =
3289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach    "BLUETOOTH_VENDOR_LIB_INTERFACE";
3389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
3489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachstatic const int INVALID_FD = -1;
3589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
3689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachnamespace {
3789ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
3889ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachusing android::hardware::bluetooth::V1_0::implementation::VendorInterface;
399041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbachusing android::hardware::hidl_vec;
4089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
414e2e8ec4e0c6635f64dedf6bd29db4fdcbd3f172Myles Watsonstruct {
424e2e8ec4e0c6635f64dedf6bd29db4fdcbd3f172Myles Watson  tINT_CMD_CBACK cb;
434e2e8ec4e0c6635f64dedf6bd29db4fdcbd3f172Myles Watson  uint16_t opcode;
444e2e8ec4e0c6635f64dedf6bd29db4fdcbd3f172Myles Watson} internal_command;
45a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watson
46beb13b45c054cdab15943188da6677984e1517d0Myles Watson// True when LPM is not enabled yet or wake is not asserted.
47beb13b45c054cdab15943188da6677984e1517d0Myles Watsonbool lpm_wake_deasserted;
48beb13b45c054cdab15943188da6677984e1517d0Myles Watsonuint32_t lpm_timeout_ms;
49beb13b45c054cdab15943188da6677984e1517d0Myles Watsonbool recent_activity_flag;
50beb13b45c054cdab15943188da6677984e1517d0Myles Watson
5189ba5284e33789c598017235e45a58dd477f9a63Andre EisenbachVendorInterface* g_vendor_interface = nullptr;
52424ffd0da56d818510000acd56b23824c960d7d7Lianchao Songstd::mutex wakeup_mutex_;
5389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
549041d97812134889d0b00541d1fe517c2b23fe74Andre EisenbachHC_BT_HDR* WrapPacketAndCopy(uint16_t event, const hidl_vec<uint8_t>& data) {
5589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  size_t packet_size = data.size() + sizeof(HC_BT_HDR);
5689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  HC_BT_HDR* packet = reinterpret_cast<HC_BT_HDR*>(new uint8_t[packet_size]);
5789ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  packet->offset = 0;
5889ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  packet->len = data.size();
5989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  packet->layer_specific = 0;
6089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  packet->event = event;
616a7d62226403d8081fbe22dbb3c41af4684fe0e4Myles Watson  // TODO(eisenbach): Avoid copy here; if BT_HDR->data can be ensured to
6289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  // be the only way the data is accessed, a pointer could be passed here...
6389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  memcpy(packet->data, data.data(), data.size());
6489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  return packet;
6589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
6689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
67a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watsonbool internal_command_event_match(const hidl_vec<uint8_t>& packet) {
68a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watson  uint8_t event_code = packet[0];
69a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watson  if (event_code != HCI_COMMAND_COMPLETE_EVENT) {
70a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watson    ALOGE("%s: Unhandled event type %02X", __func__, event_code);
71a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watson    return false;
72a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watson  }
73a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watson
74a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watson  size_t opcode_offset = HCI_EVENT_PREAMBLE_SIZE + 1;  // Skip num packets.
75a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watson
76a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watson  uint16_t opcode = packet[opcode_offset] | (packet[opcode_offset + 1] << 8);
77a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watson
784e2e8ec4e0c6635f64dedf6bd29db4fdcbd3f172Myles Watson  ALOGV("%s internal_command.opcode = %04X opcode = %04x", __func__,
794e2e8ec4e0c6635f64dedf6bd29db4fdcbd3f172Myles Watson        internal_command.opcode, opcode);
804e2e8ec4e0c6635f64dedf6bd29db4fdcbd3f172Myles Watson  return opcode == internal_command.opcode;
81a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watson}
82a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watson
8389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachuint8_t transmit_cb(uint16_t opcode, void* buffer, tINT_CMD_CBACK callback) {
84a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watson  ALOGV("%s opcode: 0x%04x, ptr: %p, cb: %p", __func__, opcode, buffer,
85a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watson        callback);
864e2e8ec4e0c6635f64dedf6bd29db4fdcbd3f172Myles Watson  internal_command.cb = callback;
874e2e8ec4e0c6635f64dedf6bd29db4fdcbd3f172Myles Watson  internal_command.opcode = opcode;
8889ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  uint8_t type = HCI_PACKET_TYPE_COMMAND;
899041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach  HC_BT_HDR* bt_hdr = reinterpret_cast<HC_BT_HDR*>(buffer);
90df765eab604919a8bfd6e0cae632348325377ef5Myles Watson  VendorInterface::get()->Send(type, bt_hdr->data, bt_hdr->len);
914e2e8ec4e0c6635f64dedf6bd29db4fdcbd3f172Myles Watson  delete[] reinterpret_cast<uint8_t*>(buffer);
9289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  return true;
9389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
9489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
9589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachvoid firmware_config_cb(bt_vendor_op_result_t result) {
969041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach  ALOGV("%s result: %d", __func__, result);
9789ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  VendorInterface::get()->OnFirmwareConfigured(result);
9889ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
9989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
10089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachvoid sco_config_cb(bt_vendor_op_result_t result) {
10189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  ALOGD("%s result: %d", __func__, result);
10289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
10389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
10489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachvoid low_power_mode_cb(bt_vendor_op_result_t result) {
10589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  ALOGD("%s result: %d", __func__, result);
10689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
10789ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
10889ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachvoid sco_audiostate_cb(bt_vendor_op_result_t result) {
10989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  ALOGD("%s result: %d", __func__, result);
11089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
11189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
11289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachvoid* buffer_alloc_cb(int size) {
11389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  void* p = new uint8_t[size];
11489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  ALOGV("%s pts: %p, size: %d", __func__, p, size);
11589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  return p;
11689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
11789ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
11889ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachvoid buffer_free_cb(void* buffer) {
11989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  ALOGV("%s ptr: %p", __func__, buffer);
12089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  delete[] reinterpret_cast<uint8_t*>(buffer);
12189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
12289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
12389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachvoid epilog_cb(bt_vendor_op_result_t result) {
12489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  ALOGD("%s result: %d", __func__, result);
12589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
12689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
12789ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachvoid a2dp_offload_cb(bt_vendor_op_result_t result, bt_vendor_opcode_t op,
12889ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach                     uint8_t av_handle) {
12989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  ALOGD("%s result: %d, op: %d, handle: %d", __func__, result, op, av_handle);
13089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
13189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
13289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachconst bt_vendor_callbacks_t lib_callbacks = {
13389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach    sizeof(lib_callbacks), firmware_config_cb, sco_config_cb,
13489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach    low_power_mode_cb,     sco_audiostate_cb,  buffer_alloc_cb,
13589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach    buffer_free_cb,        transmit_cb,        epilog_cb,
13689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach    a2dp_offload_cb};
13789ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
13889ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}  // namespace
13989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
14089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachnamespace android {
14189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachnamespace hardware {
14289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachnamespace bluetooth {
14389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachnamespace V1_0 {
14489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachnamespace implementation {
14589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
1469041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbachclass FirmwareStartupTimer {
1479041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach public:
1489041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach  FirmwareStartupTimer() : start_time_(std::chrono::steady_clock::now()) {}
1499041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach
1509041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach  ~FirmwareStartupTimer() {
1519041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach    std::chrono::duration<double> duration =
1529041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach        std::chrono::steady_clock::now() - start_time_;
1539041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach    double s = duration.count();
1549041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach    if (s == 0) return;
1558ffcbc77971ff81e346e592ce2be9a3357e971d8Myles Watson    ALOGI("Firmware configured in %.3fs", s);
1569041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach  }
1579041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach
1589041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach private:
1599041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach  std::chrono::steady_clock::time_point start_time_;
1609041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach};
1619041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach
1629041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbachbool VendorInterface::Initialize(
1639041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach    InitializeCompleteCallback initialize_complete_cb,
164917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    PacketReadCallback event_cb, PacketReadCallback acl_cb,
165917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    PacketReadCallback sco_cb) {
1669833109a3e8cb5d4935e7288af435fbef1ca6c75Myles Watson  if (g_vendor_interface) {
1679833109a3e8cb5d4935e7288af435fbef1ca6c75Myles Watson    ALOGE("%s: No previous Shutdown()?", __func__);
1689833109a3e8cb5d4935e7288af435fbef1ca6c75Myles Watson    return false;
1699833109a3e8cb5d4935e7288af435fbef1ca6c75Myles Watson  }
17089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  g_vendor_interface = new VendorInterface();
171917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson  return g_vendor_interface->Open(initialize_complete_cb, event_cb, acl_cb,
172917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson                                  sco_cb);
17389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
17489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
17589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachvoid VendorInterface::Shutdown() {
1763e272a70763ff6191ac96d8560724e0a02f827acMyles Watson  LOG_ALWAYS_FATAL_IF(!g_vendor_interface, "%s: No Vendor interface!",
1773e272a70763ff6191ac96d8560724e0a02f827acMyles Watson                      __func__);
17889ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  g_vendor_interface->Close();
17989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  delete g_vendor_interface;
18089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  g_vendor_interface = nullptr;
18189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
18289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
18389ba5284e33789c598017235e45a58dd477f9a63Andre EisenbachVendorInterface* VendorInterface::get() { return g_vendor_interface; }
18489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
1859041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbachbool VendorInterface::Open(InitializeCompleteCallback initialize_complete_cb,
186917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson                           PacketReadCallback event_cb,
187917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson                           PacketReadCallback acl_cb,
188917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson                           PacketReadCallback sco_cb) {
1899041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach  initialize_complete_cb_ = initialize_complete_cb;
19089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
19189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  // Initialize vendor interface
19289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
19389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  lib_handle_ = dlopen(VENDOR_LIBRARY_NAME, RTLD_NOW);
19489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  if (!lib_handle_) {
19589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach    ALOGE("%s unable to open %s (%s)", __func__, VENDOR_LIBRARY_NAME,
19689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach          dlerror());
19789ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach    return false;
19889ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  }
19989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
20089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  lib_interface_ = reinterpret_cast<bt_vendor_interface_t*>(
20189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach      dlsym(lib_handle_, VENDOR_LIBRARY_SYMBOL_NAME));
20289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  if (!lib_interface_) {
20389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach    ALOGE("%s unable to find symbol %s in %s (%s)", __func__,
20489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach          VENDOR_LIBRARY_SYMBOL_NAME, VENDOR_LIBRARY_NAME, dlerror());
20589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach    return false;
20689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  }
20789ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
2086a7d62226403d8081fbe22dbb3c41af4684fe0e4Myles Watson  // Get the local BD address
2096a7d62226403d8081fbe22dbb3c41af4684fe0e4Myles Watson
2106a7d62226403d8081fbe22dbb3c41af4684fe0e4Myles Watson  uint8_t local_bda[BluetoothAddress::kBytes];
2113e272a70763ff6191ac96d8560724e0a02f827acMyles Watson  if (!BluetoothAddress::get_local_address(local_bda)) {
2123e272a70763ff6191ac96d8560724e0a02f827acMyles Watson    LOG_ALWAYS_FATAL("%s: No Bluetooth Address!", __func__);
2133e272a70763ff6191ac96d8560724e0a02f827acMyles Watson  }
21489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  int status = lib_interface_->init(&lib_callbacks, (unsigned char*)local_bda);
21589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  if (status) {
21689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach    ALOGE("%s unable to initialize vendor library: %d", __func__, status);
21789ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach    return false;
21889ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  }
21989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
22089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  ALOGD("%s vendor library loaded", __func__);
22189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
222c0aee0ce877bba6e14e6582935c07f4ada50b9ddMyles Watson  // Power on the controller
22389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
224c0aee0ce877bba6e14e6582935c07f4ada50b9ddMyles Watson  int power_state = BT_VND_PWR_ON;
22589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  lib_interface_->op(BT_VND_OP_POWER_CTRL, &power_state);
22689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
227917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson  // Get the UART socket(s)
22889ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
22989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  int fd_list[CH_MAX] = {0};
23089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  int fd_count = lib_interface_->op(BT_VND_OP_USERIAL_OPEN, &fd_list);
23189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
232ec1eda69b6e41cc7d5d2a520c87602e4dcd8353dMyles Watson  if (fd_count < 1 || fd_count > CH_MAX - 1) {
233ec1eda69b6e41cc7d5d2a520c87602e4dcd8353dMyles Watson    ALOGE("%s: fd_count %d is invalid!", __func__, fd_count);
234ec1eda69b6e41cc7d5d2a520c87602e4dcd8353dMyles Watson    return false;
235ec1eda69b6e41cc7d5d2a520c87602e4dcd8353dMyles Watson  }
236ec1eda69b6e41cc7d5d2a520c87602e4dcd8353dMyles Watson
237917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson  for (int i = 0; i < fd_count; i++) {
238917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    if (fd_list[i] == INVALID_FD) {
239917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson      ALOGE("%s: fd %d is invalid!", __func__, fd_list[i]);
240917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson      return false;
241917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    }
24289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  }
24389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
244917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson  event_cb_ = event_cb;
245917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson  PacketReadCallback intercept_events = [this](const hidl_vec<uint8_t>& event) {
246917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    HandleIncomingEvent(event);
247917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson  };
248917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson
249917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson  if (fd_count == 1) {
250917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    hci::H4Protocol* h4_hci =
251917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson        new hci::H4Protocol(fd_list[0], intercept_events, acl_cb, sco_cb);
252917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    fd_watcher_.WatchFdForNonBlockingReads(
253917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson        fd_list[0], [h4_hci](int fd) { h4_hci->OnDataReady(fd); });
254917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    hci_ = h4_hci;
255917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson  } else {
256917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    hci::MctProtocol* mct_hci =
257917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson        new hci::MctProtocol(fd_list, intercept_events, acl_cb);
258917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    fd_watcher_.WatchFdForNonBlockingReads(
259917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson        fd_list[CH_EVT], [mct_hci](int fd) { mct_hci->OnEventDataReady(fd); });
260fed25ad2562661227343a68085376f1649ecbdd3Zach Johnson    fd_watcher_.WatchFdForNonBlockingReads(
261fed25ad2562661227343a68085376f1649ecbdd3Zach Johnson        fd_list[CH_ACL_IN],
262fed25ad2562661227343a68085376f1649ecbdd3Zach Johnson        [mct_hci](int fd) { mct_hci->OnAclDataReady(fd); });
263917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    hci_ = mct_hci;
26489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  }
26589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
266beb13b45c054cdab15943188da6677984e1517d0Myles Watson  // Initially, the power management is off.
267f60aeb446261cc859d28e79b6eb32402bc81cb3aAndre Eisenbach  lpm_wake_deasserted = true;
268beb13b45c054cdab15943188da6677984e1517d0Myles Watson
26989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  // Start configuring the firmware
2709041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach  firmware_startup_timer_ = new FirmwareStartupTimer();
27189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  lib_interface_->op(BT_VND_OP_FW_CFG, nullptr);
27289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
27389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  return true;
27489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
27589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
27689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachvoid VendorInterface::Close() {
2778a9efb6e354f184ee5b003fd40fad70f2d69c7cbAndre Eisenbach  // These callbacks may send HCI events (vendor-dependent), so make sure to
2788a9efb6e354f184ee5b003fd40fad70f2d69c7cbAndre Eisenbach  // StopWatching the file descriptor after this.
2798a9efb6e354f184ee5b003fd40fad70f2d69c7cbAndre Eisenbach  if (lib_interface_ != nullptr) {
2808a9efb6e354f184ee5b003fd40fad70f2d69c7cbAndre Eisenbach    bt_vendor_lpm_mode_t mode = BT_VND_LPM_DISABLE;
2818a9efb6e354f184ee5b003fd40fad70f2d69c7cbAndre Eisenbach    lib_interface_->op(BT_VND_OP_LPM_SET_MODE, &mode);
2828a9efb6e354f184ee5b003fd40fad70f2d69c7cbAndre Eisenbach  }
2838a9efb6e354f184ee5b003fd40fad70f2d69c7cbAndre Eisenbach
284f3a3cb7a601d6883ee26454a4b5509cdbe778164Myles Watson  fd_watcher_.StopWatchingFileDescriptors();
28589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
286917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson  if (hci_ != nullptr) {
287917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    delete hci_;
288917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    hci_ = nullptr;
289917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson  }
290917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson
29189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  if (lib_interface_ != nullptr) {
29289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach    lib_interface_->op(BT_VND_OP_USERIAL_CLOSE, nullptr);
29366a4ca3c928c08f2aa96a5ba1b60e93fa156d26cMyles Watson
29466a4ca3c928c08f2aa96a5ba1b60e93fa156d26cMyles Watson    int power_state = BT_VND_PWR_OFF;
29566a4ca3c928c08f2aa96a5ba1b60e93fa156d26cMyles Watson    lib_interface_->op(BT_VND_OP_POWER_CTRL, &power_state);
2969eee83093faf0edd023920b16f5251a17ae97f00Myles Watson
2979eee83093faf0edd023920b16f5251a17ae97f00Myles Watson    lib_interface_->cleanup();
29889ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  }
29989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
30089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  if (lib_handle_ != nullptr) {
30189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach    dlclose(lib_handle_);
30289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach    lib_handle_ = nullptr;
30389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  }
30489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
3059041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach  if (firmware_startup_timer_ != nullptr) {
3069041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach    delete firmware_startup_timer_;
3079041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach    firmware_startup_timer_ = nullptr;
30889ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  }
30989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
31089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
311df765eab604919a8bfd6e0cae632348325377ef5Myles Watsonsize_t VendorInterface::Send(uint8_t type, const uint8_t* data, size_t length) {
312424ffd0da56d818510000acd56b23824c960d7d7Lianchao Song  std::unique_lock<std::mutex> lock(wakeup_mutex_);
313beb13b45c054cdab15943188da6677984e1517d0Myles Watson  recent_activity_flag = true;
314beb13b45c054cdab15943188da6677984e1517d0Myles Watson
315beb13b45c054cdab15943188da6677984e1517d0Myles Watson  if (lpm_wake_deasserted == true) {
316beb13b45c054cdab15943188da6677984e1517d0Myles Watson    // Restart the timer.
317beb13b45c054cdab15943188da6677984e1517d0Myles Watson    fd_watcher_.ConfigureTimeout(std::chrono::milliseconds(lpm_timeout_ms),
318beb13b45c054cdab15943188da6677984e1517d0Myles Watson                                 [this]() { OnTimeout(); });
319beb13b45c054cdab15943188da6677984e1517d0Myles Watson    // Assert wake.
320beb13b45c054cdab15943188da6677984e1517d0Myles Watson    lpm_wake_deasserted = false;
321beb13b45c054cdab15943188da6677984e1517d0Myles Watson    bt_vendor_lpm_wake_state_t wakeState = BT_VND_LPM_WAKE_ASSERT;
322beb13b45c054cdab15943188da6677984e1517d0Myles Watson    lib_interface_->op(BT_VND_OP_LPM_WAKE_SET_STATE, &wakeState);
323beb13b45c054cdab15943188da6677984e1517d0Myles Watson    ALOGV("%s: Sent wake before (%02x)", __func__, data[0] | (data[1] << 8));
324beb13b45c054cdab15943188da6677984e1517d0Myles Watson  }
325beb13b45c054cdab15943188da6677984e1517d0Myles Watson
326917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson  return hci_->Send(type, data, length);
32789ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
32889ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
32989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachvoid VendorInterface::OnFirmwareConfigured(uint8_t result) {
3309041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach  ALOGD("%s result: %d", __func__, result);
3319041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach
3329041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach  if (firmware_startup_timer_ != nullptr) {
3339041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach    delete firmware_startup_timer_;
3349041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach    firmware_startup_timer_ = nullptr;
3359041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach  }
3369041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach
3379041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach  if (initialize_complete_cb_ != nullptr) {
3389041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach    initialize_complete_cb_(result == 0);
3399041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach    initialize_complete_cb_ = nullptr;
3409041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach  }
341beb13b45c054cdab15943188da6677984e1517d0Myles Watson
342beb13b45c054cdab15943188da6677984e1517d0Myles Watson  lib_interface_->op(BT_VND_OP_GET_LPM_IDLE_TIMEOUT, &lpm_timeout_ms);
343beb13b45c054cdab15943188da6677984e1517d0Myles Watson  ALOGI("%s: lpm_timeout_ms %d", __func__, lpm_timeout_ms);
344beb13b45c054cdab15943188da6677984e1517d0Myles Watson
345beb13b45c054cdab15943188da6677984e1517d0Myles Watson  bt_vendor_lpm_mode_t mode = BT_VND_LPM_ENABLE;
346beb13b45c054cdab15943188da6677984e1517d0Myles Watson  lib_interface_->op(BT_VND_OP_LPM_SET_MODE, &mode);
347beb13b45c054cdab15943188da6677984e1517d0Myles Watson
348beb13b45c054cdab15943188da6677984e1517d0Myles Watson  ALOGD("%s Calling StartLowPowerWatchdog()", __func__);
349beb13b45c054cdab15943188da6677984e1517d0Myles Watson  fd_watcher_.ConfigureTimeout(std::chrono::milliseconds(lpm_timeout_ms),
350beb13b45c054cdab15943188da6677984e1517d0Myles Watson                               [this]() { OnTimeout(); });
351beb13b45c054cdab15943188da6677984e1517d0Myles Watson}
352beb13b45c054cdab15943188da6677984e1517d0Myles Watson
353beb13b45c054cdab15943188da6677984e1517d0Myles Watsonvoid VendorInterface::OnTimeout() {
354beb13b45c054cdab15943188da6677984e1517d0Myles Watson  ALOGV("%s", __func__);
355424ffd0da56d818510000acd56b23824c960d7d7Lianchao Song  std::unique_lock<std::mutex> lock(wakeup_mutex_);
356beb13b45c054cdab15943188da6677984e1517d0Myles Watson  if (recent_activity_flag == false) {
357beb13b45c054cdab15943188da6677984e1517d0Myles Watson    lpm_wake_deasserted = true;
358beb13b45c054cdab15943188da6677984e1517d0Myles Watson    bt_vendor_lpm_wake_state_t wakeState = BT_VND_LPM_WAKE_DEASSERT;
359beb13b45c054cdab15943188da6677984e1517d0Myles Watson    lib_interface_->op(BT_VND_OP_LPM_WAKE_SET_STATE, &wakeState);
360beb13b45c054cdab15943188da6677984e1517d0Myles Watson    fd_watcher_.ConfigureTimeout(std::chrono::seconds(0), []() {
361beb13b45c054cdab15943188da6677984e1517d0Myles Watson      ALOGE("Zero timeout! Should never happen.");
362beb13b45c054cdab15943188da6677984e1517d0Myles Watson    });
363beb13b45c054cdab15943188da6677984e1517d0Myles Watson  }
364beb13b45c054cdab15943188da6677984e1517d0Myles Watson  recent_activity_flag = false;
36589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
36689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
367917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnsonvoid VendorInterface::HandleIncomingEvent(const hidl_vec<uint8_t>& hci_packet) {
368917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson  if (internal_command.cb != nullptr &&
369917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson      internal_command_event_match(hci_packet)) {
370917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    HC_BT_HDR* bt_hdr = WrapPacketAndCopy(HCI_PACKET_TYPE_EVENT, hci_packet);
371917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson
372917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    // The callbacks can send new commands, so don't zero after calling.
373917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    tINT_CMD_CBACK saved_cb = internal_command.cb;
374917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    internal_command.cb = nullptr;
375917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    saved_cb(bt_hdr);
376917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson  } else {
377917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    event_cb_(hci_packet);
378917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson  }
37989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
38089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
38189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}  // namespace implementation
38289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}  // namespace V1_0
38389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}  // namespace bluetooth
38489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}  // namespace hardware
38589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}  // namespace android
386