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
193d0263f0eb8c6a75bddb09f9eda6f4ac563f14d6Dan Albert#include <assert.h>
203d0263f0eb8c6a75bddb09f9eda6f4ac563f14d6Dan Albert
2189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach#define LOG_TAG "android.hardware.bluetooth@1.0-impl"
2289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach#include <android-base/logging.h>
236a7d62226403d8081fbe22dbb3c41af4684fe0e4Myles Watson#include <cutils/properties.h>
2489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach#include <utils/Log.h>
2589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
2689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach#include <dlfcn.h>
276a7d62226403d8081fbe22dbb3c41af4684fe0e4Myles Watson#include <fcntl.h>
286a7d62226403d8081fbe22dbb3c41af4684fe0e4Myles Watson
296a7d62226403d8081fbe22dbb3c41af4684fe0e4Myles Watson#include "bluetooth_address.h"
30917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson#include "h4_protocol.h"
31917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson#include "mct_protocol.h"
3289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
3389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachstatic const char* VENDOR_LIBRARY_NAME = "libbt-vendor.so";
3489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachstatic const char* VENDOR_LIBRARY_SYMBOL_NAME =
3589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach    "BLUETOOTH_VENDOR_LIB_INTERFACE";
3689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
3789ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachstatic const int INVALID_FD = -1;
3889ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
3989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachnamespace {
4089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
4189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachusing android::hardware::bluetooth::V1_0::implementation::VendorInterface;
429041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbachusing android::hardware::hidl_vec;
4389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
444e2e8ec4e0c6635f64dedf6bd29db4fdcbd3f172Myles Watsonstruct {
454e2e8ec4e0c6635f64dedf6bd29db4fdcbd3f172Myles Watson  tINT_CMD_CBACK cb;
464e2e8ec4e0c6635f64dedf6bd29db4fdcbd3f172Myles Watson  uint16_t opcode;
474e2e8ec4e0c6635f64dedf6bd29db4fdcbd3f172Myles Watson} internal_command;
48a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watson
49beb13b45c054cdab15943188da6677984e1517d0Myles Watson// True when LPM is not enabled yet or wake is not asserted.
50beb13b45c054cdab15943188da6677984e1517d0Myles Watsonbool lpm_wake_deasserted;
51beb13b45c054cdab15943188da6677984e1517d0Myles Watsonuint32_t lpm_timeout_ms;
52beb13b45c054cdab15943188da6677984e1517d0Myles Watsonbool recent_activity_flag;
53beb13b45c054cdab15943188da6677984e1517d0Myles Watson
5489ba5284e33789c598017235e45a58dd477f9a63Andre EisenbachVendorInterface* g_vendor_interface = nullptr;
5589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
569041d97812134889d0b00541d1fe517c2b23fe74Andre EisenbachHC_BT_HDR* WrapPacketAndCopy(uint16_t event, const hidl_vec<uint8_t>& data) {
5789ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  size_t packet_size = data.size() + sizeof(HC_BT_HDR);
5889ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  HC_BT_HDR* packet = reinterpret_cast<HC_BT_HDR*>(new uint8_t[packet_size]);
5989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  packet->offset = 0;
6089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  packet->len = data.size();
6189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  packet->layer_specific = 0;
6289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  packet->event = event;
636a7d62226403d8081fbe22dbb3c41af4684fe0e4Myles Watson  // TODO(eisenbach): Avoid copy here; if BT_HDR->data can be ensured to
6489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  // be the only way the data is accessed, a pointer could be passed here...
6589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  memcpy(packet->data, data.data(), data.size());
6689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  return packet;
6789ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
6889ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
69a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watsonbool internal_command_event_match(const hidl_vec<uint8_t>& packet) {
70a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watson  uint8_t event_code = packet[0];
71a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watson  if (event_code != HCI_COMMAND_COMPLETE_EVENT) {
72a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watson    ALOGE("%s: Unhandled event type %02X", __func__, event_code);
73a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watson    return false;
74a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watson  }
75a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watson
76a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watson  size_t opcode_offset = HCI_EVENT_PREAMBLE_SIZE + 1;  // Skip num packets.
77a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watson
78a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watson  uint16_t opcode = packet[opcode_offset] | (packet[opcode_offset + 1] << 8);
79a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watson
804e2e8ec4e0c6635f64dedf6bd29db4fdcbd3f172Myles Watson  ALOGV("%s internal_command.opcode = %04X opcode = %04x", __func__,
814e2e8ec4e0c6635f64dedf6bd29db4fdcbd3f172Myles Watson        internal_command.opcode, opcode);
824e2e8ec4e0c6635f64dedf6bd29db4fdcbd3f172Myles Watson  return opcode == internal_command.opcode;
83a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watson}
84a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watson
8589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachuint8_t transmit_cb(uint16_t opcode, void* buffer, tINT_CMD_CBACK callback) {
86a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watson  ALOGV("%s opcode: 0x%04x, ptr: %p, cb: %p", __func__, opcode, buffer,
87a7d33b3636ebafdb404f8d1ee910ec58bcc92e46Myles Watson        callback);
884e2e8ec4e0c6635f64dedf6bd29db4fdcbd3f172Myles Watson  internal_command.cb = callback;
894e2e8ec4e0c6635f64dedf6bd29db4fdcbd3f172Myles Watson  internal_command.opcode = opcode;
9089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  uint8_t type = HCI_PACKET_TYPE_COMMAND;
919041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach  HC_BT_HDR* bt_hdr = reinterpret_cast<HC_BT_HDR*>(buffer);
92df765eab604919a8bfd6e0cae632348325377ef5Myles Watson  VendorInterface::get()->Send(type, bt_hdr->data, bt_hdr->len);
934e2e8ec4e0c6635f64dedf6bd29db4fdcbd3f172Myles Watson  delete[] reinterpret_cast<uint8_t*>(buffer);
9489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  return true;
9589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
9689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
9789ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachvoid firmware_config_cb(bt_vendor_op_result_t result) {
989041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach  ALOGV("%s result: %d", __func__, result);
9989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  VendorInterface::get()->OnFirmwareConfigured(result);
10089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
10189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
10289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachvoid sco_config_cb(bt_vendor_op_result_t result) {
10389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  ALOGD("%s result: %d", __func__, result);
10489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
10589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
10689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachvoid low_power_mode_cb(bt_vendor_op_result_t result) {
10789ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  ALOGD("%s result: %d", __func__, result);
10889ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
10989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
11089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachvoid sco_audiostate_cb(bt_vendor_op_result_t result) {
11189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  ALOGD("%s result: %d", __func__, result);
11289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
11389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
11489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachvoid* buffer_alloc_cb(int size) {
11589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  void* p = new uint8_t[size];
11689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  ALOGV("%s pts: %p, size: %d", __func__, p, size);
11789ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  return p;
11889ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
11989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
12089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachvoid buffer_free_cb(void* buffer) {
12189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  ALOGV("%s ptr: %p", __func__, buffer);
12289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  delete[] reinterpret_cast<uint8_t*>(buffer);
12389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
12489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
12589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachvoid epilog_cb(bt_vendor_op_result_t result) {
12689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  ALOGD("%s result: %d", __func__, result);
12789ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
12889ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
12989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachvoid a2dp_offload_cb(bt_vendor_op_result_t result, bt_vendor_opcode_t op,
13089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach                     uint8_t av_handle) {
13189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  ALOGD("%s result: %d, op: %d, handle: %d", __func__, result, op, av_handle);
13289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
13389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
13489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachconst bt_vendor_callbacks_t lib_callbacks = {
13589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach    sizeof(lib_callbacks), firmware_config_cb, sco_config_cb,
13689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach    low_power_mode_cb,     sco_audiostate_cb,  buffer_alloc_cb,
13789ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach    buffer_free_cb,        transmit_cb,        epilog_cb,
13889ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach    a2dp_offload_cb};
13989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
14089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}  // namespace
14189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
14289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachnamespace android {
14389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachnamespace hardware {
14489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachnamespace bluetooth {
14589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachnamespace V1_0 {
14689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachnamespace implementation {
14789ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
1489041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbachclass FirmwareStartupTimer {
1499041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach public:
1509041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach  FirmwareStartupTimer() : start_time_(std::chrono::steady_clock::now()) {}
1519041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach
1529041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach  ~FirmwareStartupTimer() {
1539041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach    std::chrono::duration<double> duration =
1549041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach        std::chrono::steady_clock::now() - start_time_;
1559041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach    double s = duration.count();
1569041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach    if (s == 0) return;
1578ffcbc77971ff81e346e592ce2be9a3357e971d8Myles Watson    ALOGI("Firmware configured in %.3fs", s);
1589041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach  }
1599041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach
1609041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach private:
1619041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach  std::chrono::steady_clock::time_point start_time_;
1629041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach};
1639041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach
1649041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbachbool VendorInterface::Initialize(
1659041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach    InitializeCompleteCallback initialize_complete_cb,
166917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    PacketReadCallback event_cb, PacketReadCallback acl_cb,
167917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    PacketReadCallback sco_cb) {
16889ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  assert(!g_vendor_interface);
16989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  g_vendor_interface = new VendorInterface();
170917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson  return g_vendor_interface->Open(initialize_complete_cb, event_cb, acl_cb,
171917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson                                  sco_cb);
17289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
17389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
17489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachvoid VendorInterface::Shutdown() {
17589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  CHECK(g_vendor_interface);
17689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  g_vendor_interface->Close();
17789ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  delete g_vendor_interface;
17889ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  g_vendor_interface = nullptr;
17989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
18089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
18189ba5284e33789c598017235e45a58dd477f9a63Andre EisenbachVendorInterface* VendorInterface::get() { return g_vendor_interface; }
18289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
1839041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbachbool VendorInterface::Open(InitializeCompleteCallback initialize_complete_cb,
184917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson                           PacketReadCallback event_cb,
185917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson                           PacketReadCallback acl_cb,
186917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson                           PacketReadCallback sco_cb) {
1879041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach  initialize_complete_cb_ = initialize_complete_cb;
18889ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
18989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  // Initialize vendor interface
19089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
19189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  lib_handle_ = dlopen(VENDOR_LIBRARY_NAME, RTLD_NOW);
19289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  if (!lib_handle_) {
19389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach    ALOGE("%s unable to open %s (%s)", __func__, VENDOR_LIBRARY_NAME,
19489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach          dlerror());
19589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach    return false;
19689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  }
19789ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
19889ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  lib_interface_ = reinterpret_cast<bt_vendor_interface_t*>(
19989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach      dlsym(lib_handle_, VENDOR_LIBRARY_SYMBOL_NAME));
20089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  if (!lib_interface_) {
20189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach    ALOGE("%s unable to find symbol %s in %s (%s)", __func__,
20289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach          VENDOR_LIBRARY_SYMBOL_NAME, VENDOR_LIBRARY_NAME, dlerror());
20389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach    return false;
20489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  }
20589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
2066a7d62226403d8081fbe22dbb3c41af4684fe0e4Myles Watson  // Get the local BD address
2076a7d62226403d8081fbe22dbb3c41af4684fe0e4Myles Watson
2086a7d62226403d8081fbe22dbb3c41af4684fe0e4Myles Watson  uint8_t local_bda[BluetoothAddress::kBytes];
2096a7d62226403d8081fbe22dbb3c41af4684fe0e4Myles Watson  CHECK(BluetoothAddress::get_local_address(local_bda));
21089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  int status = lib_interface_->init(&lib_callbacks, (unsigned char*)local_bda);
21189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  if (status) {
21289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach    ALOGE("%s unable to initialize vendor library: %d", __func__, status);
21389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach    return false;
21489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  }
21589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
21689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  ALOGD("%s vendor library loaded", __func__);
21789ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
218c0aee0ce877bba6e14e6582935c07f4ada50b9ddMyles Watson  // Power on the controller
21989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
220c0aee0ce877bba6e14e6582935c07f4ada50b9ddMyles Watson  int power_state = BT_VND_PWR_ON;
22189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  lib_interface_->op(BT_VND_OP_POWER_CTRL, &power_state);
22289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
223917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson  // Get the UART socket(s)
22489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
22589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  int fd_list[CH_MAX] = {0};
22689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  int fd_count = lib_interface_->op(BT_VND_OP_USERIAL_OPEN, &fd_list);
22789ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
228917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson  for (int i = 0; i < fd_count; i++) {
229917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    if (fd_list[i] == INVALID_FD) {
230917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson      ALOGE("%s: fd %d is invalid!", __func__, fd_list[i]);
231917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson      return false;
232917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    }
23389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  }
23489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
235917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson  event_cb_ = event_cb;
236917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson  PacketReadCallback intercept_events = [this](const hidl_vec<uint8_t>& event) {
237917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    HandleIncomingEvent(event);
238917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson  };
239917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson
240917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson  if (fd_count == 1) {
241917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    hci::H4Protocol* h4_hci =
242917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson        new hci::H4Protocol(fd_list[0], intercept_events, acl_cb, sco_cb);
243917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    fd_watcher_.WatchFdForNonBlockingReads(
244917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson        fd_list[0], [h4_hci](int fd) { h4_hci->OnDataReady(fd); });
245917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    hci_ = h4_hci;
246917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson  } else {
247917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    hci::MctProtocol* mct_hci =
248917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson        new hci::MctProtocol(fd_list, intercept_events, acl_cb);
249917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    fd_watcher_.WatchFdForNonBlockingReads(
250917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson        fd_list[CH_EVT], [mct_hci](int fd) { mct_hci->OnEventDataReady(fd); });
251fed25ad2562661227343a68085376f1649ecbdd3Zach Johnson    fd_watcher_.WatchFdForNonBlockingReads(
252fed25ad2562661227343a68085376f1649ecbdd3Zach Johnson        fd_list[CH_ACL_IN],
253fed25ad2562661227343a68085376f1649ecbdd3Zach Johnson        [mct_hci](int fd) { mct_hci->OnAclDataReady(fd); });
254917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    hci_ = mct_hci;
25589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  }
25689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
257beb13b45c054cdab15943188da6677984e1517d0Myles Watson  // Initially, the power management is off.
258f60aeb446261cc859d28e79b6eb32402bc81cb3aAndre Eisenbach  lpm_wake_deasserted = true;
259beb13b45c054cdab15943188da6677984e1517d0Myles Watson
26089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  // Start configuring the firmware
2619041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach  firmware_startup_timer_ = new FirmwareStartupTimer();
26289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  lib_interface_->op(BT_VND_OP_FW_CFG, nullptr);
26389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
26489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  return true;
26589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
26689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
26789ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachvoid VendorInterface::Close() {
2688a9efb6e354f184ee5b003fd40fad70f2d69c7cbAndre Eisenbach  // These callbacks may send HCI events (vendor-dependent), so make sure to
2698a9efb6e354f184ee5b003fd40fad70f2d69c7cbAndre Eisenbach  // StopWatching the file descriptor after this.
2708a9efb6e354f184ee5b003fd40fad70f2d69c7cbAndre Eisenbach  if (lib_interface_ != nullptr) {
2718a9efb6e354f184ee5b003fd40fad70f2d69c7cbAndre Eisenbach    bt_vendor_lpm_mode_t mode = BT_VND_LPM_DISABLE;
2728a9efb6e354f184ee5b003fd40fad70f2d69c7cbAndre Eisenbach    lib_interface_->op(BT_VND_OP_LPM_SET_MODE, &mode);
2738a9efb6e354f184ee5b003fd40fad70f2d69c7cbAndre Eisenbach  }
2748a9efb6e354f184ee5b003fd40fad70f2d69c7cbAndre Eisenbach
275f3a3cb7a601d6883ee26454a4b5509cdbe778164Myles Watson  fd_watcher_.StopWatchingFileDescriptors();
27689ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
277917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson  if (hci_ != nullptr) {
278917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    delete hci_;
279917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    hci_ = nullptr;
280917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson  }
281917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson
28289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  if (lib_interface_ != nullptr) {
28389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach    lib_interface_->op(BT_VND_OP_USERIAL_CLOSE, nullptr);
28466a4ca3c928c08f2aa96a5ba1b60e93fa156d26cMyles Watson
28566a4ca3c928c08f2aa96a5ba1b60e93fa156d26cMyles Watson    int power_state = BT_VND_PWR_OFF;
28666a4ca3c928c08f2aa96a5ba1b60e93fa156d26cMyles Watson    lib_interface_->op(BT_VND_OP_POWER_CTRL, &power_state);
2875082bca12e3869de381fb7068dfcb9a23a496cfcMyles Watson
2885082bca12e3869de381fb7068dfcb9a23a496cfcMyles Watson    lib_interface_->cleanup();
28989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  }
29089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
29189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  if (lib_handle_ != nullptr) {
29289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach    dlclose(lib_handle_);
29389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach    lib_handle_ = nullptr;
29489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  }
29589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
2969041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach  if (firmware_startup_timer_ != nullptr) {
2979041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach    delete firmware_startup_timer_;
2989041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach    firmware_startup_timer_ = nullptr;
29989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach  }
30089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
30189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
302df765eab604919a8bfd6e0cae632348325377ef5Myles Watsonsize_t VendorInterface::Send(uint8_t type, const uint8_t* data, size_t length) {
303beb13b45c054cdab15943188da6677984e1517d0Myles Watson  recent_activity_flag = true;
304beb13b45c054cdab15943188da6677984e1517d0Myles Watson
305beb13b45c054cdab15943188da6677984e1517d0Myles Watson  if (lpm_wake_deasserted == true) {
306beb13b45c054cdab15943188da6677984e1517d0Myles Watson    // Restart the timer.
307beb13b45c054cdab15943188da6677984e1517d0Myles Watson    fd_watcher_.ConfigureTimeout(std::chrono::milliseconds(lpm_timeout_ms),
308beb13b45c054cdab15943188da6677984e1517d0Myles Watson                                 [this]() { OnTimeout(); });
309beb13b45c054cdab15943188da6677984e1517d0Myles Watson    // Assert wake.
310beb13b45c054cdab15943188da6677984e1517d0Myles Watson    lpm_wake_deasserted = false;
311beb13b45c054cdab15943188da6677984e1517d0Myles Watson    bt_vendor_lpm_wake_state_t wakeState = BT_VND_LPM_WAKE_ASSERT;
312beb13b45c054cdab15943188da6677984e1517d0Myles Watson    lib_interface_->op(BT_VND_OP_LPM_WAKE_SET_STATE, &wakeState);
313beb13b45c054cdab15943188da6677984e1517d0Myles Watson    ALOGV("%s: Sent wake before (%02x)", __func__, data[0] | (data[1] << 8));
314beb13b45c054cdab15943188da6677984e1517d0Myles Watson  }
315beb13b45c054cdab15943188da6677984e1517d0Myles Watson
316917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson  return hci_->Send(type, data, length);
31789ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
31889ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
31989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbachvoid VendorInterface::OnFirmwareConfigured(uint8_t result) {
3209041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach  ALOGD("%s result: %d", __func__, result);
3219041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach
3229041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach  if (firmware_startup_timer_ != nullptr) {
3239041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach    delete firmware_startup_timer_;
3249041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach    firmware_startup_timer_ = nullptr;
3259041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach  }
3269041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach
3279041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach  if (initialize_complete_cb_ != nullptr) {
3289041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach    initialize_complete_cb_(result == 0);
3299041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach    initialize_complete_cb_ = nullptr;
3309041d97812134889d0b00541d1fe517c2b23fe74Andre Eisenbach  }
331beb13b45c054cdab15943188da6677984e1517d0Myles Watson
332beb13b45c054cdab15943188da6677984e1517d0Myles Watson  lib_interface_->op(BT_VND_OP_GET_LPM_IDLE_TIMEOUT, &lpm_timeout_ms);
333beb13b45c054cdab15943188da6677984e1517d0Myles Watson  ALOGI("%s: lpm_timeout_ms %d", __func__, lpm_timeout_ms);
334beb13b45c054cdab15943188da6677984e1517d0Myles Watson
335beb13b45c054cdab15943188da6677984e1517d0Myles Watson  bt_vendor_lpm_mode_t mode = BT_VND_LPM_ENABLE;
336beb13b45c054cdab15943188da6677984e1517d0Myles Watson  lib_interface_->op(BT_VND_OP_LPM_SET_MODE, &mode);
337beb13b45c054cdab15943188da6677984e1517d0Myles Watson
338beb13b45c054cdab15943188da6677984e1517d0Myles Watson  ALOGD("%s Calling StartLowPowerWatchdog()", __func__);
339beb13b45c054cdab15943188da6677984e1517d0Myles Watson  fd_watcher_.ConfigureTimeout(std::chrono::milliseconds(lpm_timeout_ms),
340beb13b45c054cdab15943188da6677984e1517d0Myles Watson                               [this]() { OnTimeout(); });
341beb13b45c054cdab15943188da6677984e1517d0Myles Watson}
342beb13b45c054cdab15943188da6677984e1517d0Myles Watson
343beb13b45c054cdab15943188da6677984e1517d0Myles Watsonvoid VendorInterface::OnTimeout() {
344beb13b45c054cdab15943188da6677984e1517d0Myles Watson  ALOGV("%s", __func__);
345beb13b45c054cdab15943188da6677984e1517d0Myles Watson  if (recent_activity_flag == false) {
346beb13b45c054cdab15943188da6677984e1517d0Myles Watson    lpm_wake_deasserted = true;
347beb13b45c054cdab15943188da6677984e1517d0Myles Watson    bt_vendor_lpm_wake_state_t wakeState = BT_VND_LPM_WAKE_DEASSERT;
348beb13b45c054cdab15943188da6677984e1517d0Myles Watson    lib_interface_->op(BT_VND_OP_LPM_WAKE_SET_STATE, &wakeState);
349beb13b45c054cdab15943188da6677984e1517d0Myles Watson    fd_watcher_.ConfigureTimeout(std::chrono::seconds(0), []() {
350beb13b45c054cdab15943188da6677984e1517d0Myles Watson      ALOGE("Zero timeout! Should never happen.");
351beb13b45c054cdab15943188da6677984e1517d0Myles Watson    });
352beb13b45c054cdab15943188da6677984e1517d0Myles Watson  }
353beb13b45c054cdab15943188da6677984e1517d0Myles Watson  recent_activity_flag = false;
35489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
35589ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
356917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnsonvoid VendorInterface::HandleIncomingEvent(const hidl_vec<uint8_t>& hci_packet) {
357917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson  if (internal_command.cb != nullptr &&
358917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson      internal_command_event_match(hci_packet)) {
359917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    HC_BT_HDR* bt_hdr = WrapPacketAndCopy(HCI_PACKET_TYPE_EVENT, hci_packet);
360917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson
361917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    // The callbacks can send new commands, so don't zero after calling.
362917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    tINT_CMD_CBACK saved_cb = internal_command.cb;
363917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    internal_command.cb = nullptr;
364917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    saved_cb(bt_hdr);
365917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson  } else {
366917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson    event_cb_(hci_packet);
367917efb1c0e2458434390463ca11bd9be935c2e54Zach Johnson  }
36889ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}
36989ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach
37089ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}  // namespace implementation
37189ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}  // namespace V1_0
37289ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}  // namespace bluetooth
37389ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}  // namespace hardware
37489ba5284e33789c598017235e45a58dd477f9a63Andre Eisenbach}  // namespace android
375