blob: c23d667313216a519009073b387eb7f9b42fae62 [file] [log] [blame]
Andre Eisenbach89ba5282016-10-13 15:45:02 -07001//
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@1.0-impl"
Myles Watson6a7d6222016-10-13 15:45:02 -070020#include <cutils/properties.h>
Andre Eisenbach89ba5282016-10-13 15:45:02 -070021#include <utils/Log.h>
22
23#include <dlfcn.h>
Myles Watson6a7d6222016-10-13 15:45:02 -070024#include <fcntl.h>
25
26#include "bluetooth_address.h"
Zach Johnson917efb12017-02-26 23:46:05 -080027#include "h4_protocol.h"
28#include "mct_protocol.h"
Andre Eisenbach89ba5282016-10-13 15:45:02 -070029
Ayushi Khopkara37d3df2021-06-24 20:24:03 +053030#ifdef BT_FUZZER
31static const char* VENDOR_LIBRARY_NAME = "libbt-vendor-fuzz.so";
32#else
Andre Eisenbach89ba5282016-10-13 15:45:02 -070033static const char* VENDOR_LIBRARY_NAME = "libbt-vendor.so";
Ayushi Khopkara37d3df2021-06-24 20:24:03 +053034#endif
Andre Eisenbach89ba5282016-10-13 15:45:02 -070035static const char* VENDOR_LIBRARY_SYMBOL_NAME =
36 "BLUETOOTH_VENDOR_LIB_INTERFACE";
37
38static const int INVALID_FD = -1;
xiaoshun.xu1adfae92022-09-14 20:39:16 +080039std::mutex vendor_mutex_;
40std::mutex initcb_mutex_;
Andre Eisenbach89ba5282016-10-13 15:45:02 -070041
42namespace {
43
Andre Eisenbach9041d972017-01-17 18:23:12 -080044using android::hardware::hidl_vec;
Jack Hecaeab052018-10-23 18:13:51 -070045using android::hardware::bluetooth::V1_0::implementation::VendorInterface;
Andre Eisenbach89ba5282016-10-13 15:45:02 -070046
Myles Watson4e2e8ec2017-02-01 10:46:16 -080047struct {
48 tINT_CMD_CBACK cb;
49 uint16_t opcode;
50} internal_command;
Myles Watsona7d33b32017-01-24 09:09:58 -080051
xiaoshun.xu1adfae92022-09-14 20:39:16 +080052enum {
53 VENDOR_STATE_INIT = 1,
54 VENDOR_STATE_OPENING, /* during opening */
55 VENDOR_STATE_OPENED, /* open in fops_open */
56 VENDOR_STATE_CLOSING, /* during closing */
57 VENDOR_STATE_CLOSED, /* closed */
58
59 VENDOR_STATE_MSG_NUM
60} ;
61
62uint8_t vstate = VENDOR_STATE_INIT;
63
Myles Watsonbeb13b42017-01-26 10:47:27 -080064// True when LPM is not enabled yet or wake is not asserted.
65bool lpm_wake_deasserted;
66uint32_t lpm_timeout_ms;
67bool recent_activity_flag;
68
Andre Eisenbach89ba5282016-10-13 15:45:02 -070069VendorInterface* g_vendor_interface = nullptr;
xiaoshun.xu1adfae92022-09-14 20:39:16 +080070static VendorInterface vendor_interface;
Andre Eisenbach89ba5282016-10-13 15:45:02 -070071
Andre Eisenbach9041d972017-01-17 18:23:12 -080072HC_BT_HDR* WrapPacketAndCopy(uint16_t event, const hidl_vec<uint8_t>& data) {
Andre Eisenbach89ba5282016-10-13 15:45:02 -070073 size_t packet_size = data.size() + sizeof(HC_BT_HDR);
74 HC_BT_HDR* packet = reinterpret_cast<HC_BT_HDR*>(new uint8_t[packet_size]);
75 packet->offset = 0;
76 packet->len = data.size();
77 packet->layer_specific = 0;
78 packet->event = event;
Myles Watson6a7d6222016-10-13 15:45:02 -070079 // TODO(eisenbach): Avoid copy here; if BT_HDR->data can be ensured to
Andre Eisenbach89ba5282016-10-13 15:45:02 -070080 // be the only way the data is accessed, a pointer could be passed here...
81 memcpy(packet->data, data.data(), data.size());
82 return packet;
83}
84
Myles Watsona7d33b32017-01-24 09:09:58 -080085bool internal_command_event_match(const hidl_vec<uint8_t>& packet) {
86 uint8_t event_code = packet[0];
87 if (event_code != HCI_COMMAND_COMPLETE_EVENT) {
88 ALOGE("%s: Unhandled event type %02X", __func__, event_code);
89 return false;
90 }
91
92 size_t opcode_offset = HCI_EVENT_PREAMBLE_SIZE + 1; // Skip num packets.
93
94 uint16_t opcode = packet[opcode_offset] | (packet[opcode_offset + 1] << 8);
95
Myles Watson4e2e8ec2017-02-01 10:46:16 -080096 ALOGV("%s internal_command.opcode = %04X opcode = %04x", __func__,
97 internal_command.opcode, opcode);
98 return opcode == internal_command.opcode;
Myles Watsona7d33b32017-01-24 09:09:58 -080099}
100
Andre Eisenbach89ba5282016-10-13 15:45:02 -0700101uint8_t transmit_cb(uint16_t opcode, void* buffer, tINT_CMD_CBACK callback) {
Myles Watsona7d33b32017-01-24 09:09:58 -0800102 ALOGV("%s opcode: 0x%04x, ptr: %p, cb: %p", __func__, opcode, buffer,
103 callback);
Myles Watson4e2e8ec2017-02-01 10:46:16 -0800104 internal_command.cb = callback;
105 internal_command.opcode = opcode;
Andre Eisenbach89ba5282016-10-13 15:45:02 -0700106 uint8_t type = HCI_PACKET_TYPE_COMMAND;
Andre Eisenbach9041d972017-01-17 18:23:12 -0800107 HC_BT_HDR* bt_hdr = reinterpret_cast<HC_BT_HDR*>(buffer);
Myles Watsondf765ea2017-01-30 09:07:37 -0800108 VendorInterface::get()->Send(type, bt_hdr->data, bt_hdr->len);
Myles Watson4e2e8ec2017-02-01 10:46:16 -0800109 delete[] reinterpret_cast<uint8_t*>(buffer);
Andre Eisenbach89ba5282016-10-13 15:45:02 -0700110 return true;
111}
112
113void firmware_config_cb(bt_vendor_op_result_t result) {
Andre Eisenbach9041d972017-01-17 18:23:12 -0800114 ALOGV("%s result: %d", __func__, result);
Andre Eisenbach89ba5282016-10-13 15:45:02 -0700115 VendorInterface::get()->OnFirmwareConfigured(result);
116}
117
118void sco_config_cb(bt_vendor_op_result_t result) {
119 ALOGD("%s result: %d", __func__, result);
120}
121
122void low_power_mode_cb(bt_vendor_op_result_t result) {
123 ALOGD("%s result: %d", __func__, result);
124}
125
126void sco_audiostate_cb(bt_vendor_op_result_t result) {
127 ALOGD("%s result: %d", __func__, result);
128}
129
130void* buffer_alloc_cb(int size) {
131 void* p = new uint8_t[size];
132 ALOGV("%s pts: %p, size: %d", __func__, p, size);
133 return p;
134}
135
136void buffer_free_cb(void* buffer) {
137 ALOGV("%s ptr: %p", __func__, buffer);
138 delete[] reinterpret_cast<uint8_t*>(buffer);
139}
140
141void epilog_cb(bt_vendor_op_result_t result) {
142 ALOGD("%s result: %d", __func__, result);
143}
144
145void a2dp_offload_cb(bt_vendor_op_result_t result, bt_vendor_opcode_t op,
146 uint8_t av_handle) {
147 ALOGD("%s result: %d, op: %d, handle: %d", __func__, result, op, av_handle);
148}
149
150const bt_vendor_callbacks_t lib_callbacks = {
151 sizeof(lib_callbacks), firmware_config_cb, sco_config_cb,
152 low_power_mode_cb, sco_audiostate_cb, buffer_alloc_cb,
153 buffer_free_cb, transmit_cb, epilog_cb,
154 a2dp_offload_cb};
155
156} // namespace
157
158namespace android {
159namespace hardware {
160namespace bluetooth {
161namespace V1_0 {
162namespace implementation {
163
Andre Eisenbach9041d972017-01-17 18:23:12 -0800164class FirmwareStartupTimer {
165 public:
166 FirmwareStartupTimer() : start_time_(std::chrono::steady_clock::now()) {}
167
168 ~FirmwareStartupTimer() {
169 std::chrono::duration<double> duration =
170 std::chrono::steady_clock::now() - start_time_;
171 double s = duration.count();
172 if (s == 0) return;
Myles Watson8ffcbc72017-01-20 10:09:38 -0800173 ALOGI("Firmware configured in %.3fs", s);
Andre Eisenbach9041d972017-01-17 18:23:12 -0800174 }
175
176 private:
177 std::chrono::steady_clock::time_point start_time_;
178};
179
180bool VendorInterface::Initialize(
181 InitializeCompleteCallback initialize_complete_cb,
Zach Johnson917efb12017-02-26 23:46:05 -0800182 PacketReadCallback event_cb, PacketReadCallback acl_cb,
Jakub Pawlowski13b4d312019-11-05 12:27:29 +0100183 PacketReadCallback sco_cb, PacketReadCallback iso_cb) {
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800184 ALOGI("%s: VendorInterface::Initialize", __func__);
185 g_vendor_interface = &vendor_interface;
Zach Johnson917efb12017-02-26 23:46:05 -0800186 return g_vendor_interface->Open(initialize_complete_cb, event_cb, acl_cb,
Jakub Pawlowski13b4d312019-11-05 12:27:29 +0100187 sco_cb, iso_cb);
Andre Eisenbach89ba5282016-10-13 15:45:02 -0700188}
189
190void VendorInterface::Shutdown() {
Myles Watson3e272a72017-06-26 13:09:11 -0700191 LOG_ALWAYS_FATAL_IF(!g_vendor_interface, "%s: No Vendor interface!",
192 __func__);
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800193 ALOGI("%s: VendorInterface::Shutdown", __func__);
Andre Eisenbach89ba5282016-10-13 15:45:02 -0700194 g_vendor_interface->Close();
Andre Eisenbach89ba5282016-10-13 15:45:02 -0700195}
196
197VendorInterface* VendorInterface::get() { return g_vendor_interface; }
198
Andre Eisenbach9041d972017-01-17 18:23:12 -0800199bool VendorInterface::Open(InitializeCompleteCallback initialize_complete_cb,
Zach Johnson917efb12017-02-26 23:46:05 -0800200 PacketReadCallback event_cb,
201 PacketReadCallback acl_cb,
Jakub Pawlowski13b4d312019-11-05 12:27:29 +0100202 PacketReadCallback sco_cb,
203 PacketReadCallback iso_cb) {
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800204 {
205 std::unique_lock<std::mutex> guard(vendor_mutex_);
206 if (vstate == VENDOR_STATE_OPENED) {
207 ALOGW("VendorInterface opened!");
208 return true;
209 }
Andre Eisenbach89ba5282016-10-13 15:45:02 -0700210
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800211 if ((vstate == VENDOR_STATE_CLOSING) ||
212 (vstate == VENDOR_STATE_OPENING)) {
213 ALOGW("VendorInterface open/close is on-going !");
214 return true;
215 }
Andre Eisenbach89ba5282016-10-13 15:45:02 -0700216
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800217 vstate = VENDOR_STATE_OPENING;
218 ALOGI("%s: VendorInterface::Open", __func__);
Andre Eisenbach89ba5282016-10-13 15:45:02 -0700219
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800220 initialize_complete_cb_ = initialize_complete_cb;
221 // Initialize vendor interface
222
223 lib_handle_ = dlopen(VENDOR_LIBRARY_NAME, RTLD_NOW);
224 if (!lib_handle_) {
225 ALOGE("%s unable to open %s (%s)", __func__, VENDOR_LIBRARY_NAME,
226 dlerror());
227 return false;
228 }
229
230 lib_interface_ = reinterpret_cast<bt_vendor_interface_t*>(
231 dlsym(lib_handle_, VENDOR_LIBRARY_SYMBOL_NAME));
232 if (!lib_interface_) {
233 ALOGE("%s unable to find symbol %s in %s (%s)", __func__,
234 VENDOR_LIBRARY_SYMBOL_NAME, VENDOR_LIBRARY_NAME, dlerror());
235 return false;
236 }
Andre Eisenbach89ba5282016-10-13 15:45:02 -0700237
Myles Watson6a7d6222016-10-13 15:45:02 -0700238 // Get the local BD address
239
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800240 uint8_t local_bda[BluetoothAddress::kBytes] = {0, 0, 0, 0, 0, 0};
241 if (!BluetoothAddress::get_local_address(local_bda)) {
242 // BT driver will get BD address from NVRAM for MTK solution
243 ALOGW("%s: No pre-set Bluetooth Address!", __func__);
244 }
245 int status = lib_interface_->init(&lib_callbacks, (unsigned char*)local_bda);
246 if (status) {
247 ALOGE("%s unable to initialize vendor library: %d", __func__, status);
248 return false;
249 }
Andre Eisenbach89ba5282016-10-13 15:45:02 -0700250
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800251 ALOGD("%s vendor library loaded", __func__);
Andre Eisenbach89ba5282016-10-13 15:45:02 -0700252
Myles Watsonc0aee0c2017-03-13 12:35:25 -0700253 // Power on the controller
Andre Eisenbach89ba5282016-10-13 15:45:02 -0700254
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800255 int power_state = BT_VND_PWR_ON;
256 lib_interface_->op(BT_VND_OP_POWER_CTRL, &power_state);
Andre Eisenbach89ba5282016-10-13 15:45:02 -0700257
Zach Johnson917efb12017-02-26 23:46:05 -0800258 // Get the UART socket(s)
Andre Eisenbach89ba5282016-10-13 15:45:02 -0700259
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800260 int fd_list[CH_MAX] = {0};
261 int fd_count = lib_interface_->op(BT_VND_OP_USERIAL_OPEN, &fd_list);
Andre Eisenbach89ba5282016-10-13 15:45:02 -0700262
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800263 if (fd_count < 1 || fd_count > CH_MAX - 1) {
264 ALOGE("%s: fd_count %d is invalid!", __func__, fd_count);
Zach Johnson917efb12017-02-26 23:46:05 -0800265 return false;
266 }
Andre Eisenbach89ba5282016-10-13 15:45:02 -0700267
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800268 for (int i = 0; i < fd_count; i++) {
269 if (fd_list[i] == INVALID_FD) {
270 ALOGE("%s: fd %d is invalid!", __func__, fd_list[i]);
271 return false;
272 }
273 }
Zach Johnson917efb12017-02-26 23:46:05 -0800274
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800275 event_cb_ = event_cb;
276 PacketReadCallback intercept_events = [this](const hidl_vec<uint8_t>& event) {
277 HandleIncomingEvent(event);
278 };
279
280 if (fd_count == 1) {
281 hci::H4Protocol* h4_hci =
282 new hci::H4Protocol(fd_list[0], intercept_events, acl_cb, sco_cb, iso_cb);
283 fd_watcher_.WatchFdForNonBlockingReads(
284 fd_list[0], [h4_hci](int fd) { h4_hci->OnDataReady(fd); });
285 hci_ = h4_hci;
286 } else {
287 hci::MctProtocol* mct_hci =
288 new hci::MctProtocol(fd_list, intercept_events, acl_cb);
289 fd_watcher_.WatchFdForNonBlockingReads(
290 fd_list[CH_EVT], [mct_hci](int fd) { mct_hci->OnEventDataReady(fd); });
291 fd_watcher_.WatchFdForNonBlockingReads(
292 fd_list[CH_ACL_IN],
293 [mct_hci](int fd) { mct_hci->OnAclDataReady(fd); });
294 hci_ = mct_hci;
295 }
Andre Eisenbach89ba5282016-10-13 15:45:02 -0700296
Myles Watsonbeb13b42017-01-26 10:47:27 -0800297 // Initially, the power management is off.
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800298 lpm_wake_deasserted = true;
Myles Watsonbeb13b42017-01-26 10:47:27 -0800299
Andre Eisenbach89ba5282016-10-13 15:45:02 -0700300 // Start configuring the firmware
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800301 firmware_startup_timer_ = new FirmwareStartupTimer();
302 lib_interface_->op(BT_VND_OP_FW_CFG, nullptr);
Andre Eisenbach89ba5282016-10-13 15:45:02 -0700303
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800304 vstate = VENDOR_STATE_OPENED;
305 ALOGI("%s: VendorInterface::Open done!!!", __func__);
306 } // vendor_mutex_ done
Andre Eisenbach89ba5282016-10-13 15:45:02 -0700307 return true;
308}
309
310void VendorInterface::Close() {
Andre Eisenbach8a9efb62017-03-17 20:28:09 +0000311 // These callbacks may send HCI events (vendor-dependent), so make sure to
312 // StopWatching the file descriptor after this.
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800313
314 if (vstate != VENDOR_STATE_OPENED) {
315 ALOGW("VendorInterface is not allow close(%d)", vstate);
316 return;
317 }
318 vstate = VENDOR_STATE_CLOSING;
319 ALOGI("%s: VendorInterface::Close", __func__);
320
Andre Eisenbach8a9efb62017-03-17 20:28:09 +0000321 if (lib_interface_ != nullptr) {
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800322 lib_interface_->cleanup();
Andre Eisenbach8a9efb62017-03-17 20:28:09 +0000323 bt_vendor_lpm_mode_t mode = BT_VND_LPM_DISABLE;
324 lib_interface_->op(BT_VND_OP_LPM_SET_MODE, &mode);
325 }
326
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800327 {
328 std::unique_lock<std::mutex> guard(vendor_mutex_);
Andre Eisenbach89ba5282016-10-13 15:45:02 -0700329
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800330 fd_watcher_.StopWatchingFileDescriptors();
331 if (hci_ != nullptr) {
332 delete hci_;
333 hci_ = nullptr;
334 }
Zach Johnson917efb12017-02-26 23:46:05 -0800335
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800336 if (lib_interface_ != nullptr) {
337 lib_interface_->op(BT_VND_OP_USERIAL_CLOSE, nullptr);
Myles Watson66a4ca32017-03-10 09:10:51 -0800338
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800339 int power_state = BT_VND_PWR_OFF;
340 lib_interface_->op(BT_VND_OP_POWER_CTRL, &power_state);
Myles Watson9eee8302017-06-08 08:38:58 -0700341
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800342 lib_interface_ = nullptr;
343 }
Andre Eisenbach89ba5282016-10-13 15:45:02 -0700344
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800345 if (lib_handle_ != nullptr) {
346 dlclose(lib_handle_);
347 lib_handle_ = nullptr;
348 }
Andre Eisenbach89ba5282016-10-13 15:45:02 -0700349
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800350 if (firmware_startup_timer_ != nullptr) {
351 delete firmware_startup_timer_;
352 firmware_startup_timer_ = nullptr;
353 }
354 vstate = VENDOR_STATE_CLOSED;
355 } // vendor_mutex_ done
356 ALOGI("%s: VendorInterface::Close done!!!", __func__);
Andre Eisenbach89ba5282016-10-13 15:45:02 -0700357}
358
Myles Watsondf765ea2017-01-30 09:07:37 -0800359size_t VendorInterface::Send(uint8_t type, const uint8_t* data, size_t length) {
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800360 {
361 std::unique_lock<std::mutex> guard(vendor_mutex_);
Myles Watsonbeb13b42017-01-26 10:47:27 -0800362
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800363 if (vstate != VENDOR_STATE_OPENED) {
364 ALOGW("VendorInterface is not open yet(%d)!", vstate);
365 return 0;
366 }
367 ALOGI("%s: VendorInterface::Send", __func__);
368
369 if (lib_interface_ == nullptr) {
370 ALOGE("lib_interface_ is null");
371 return 0;
372 }
373 recent_activity_flag = true;
374 if (lpm_wake_deasserted == true) {
375 // Restart the timer.
376 fd_watcher_.ConfigureTimeout(std::chrono::milliseconds(lpm_timeout_ms),
Myles Watsonbeb13b42017-01-26 10:47:27 -0800377 [this]() { OnTimeout(); });
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800378 // Assert wake.
379 lpm_wake_deasserted = false;
380 bt_vendor_lpm_wake_state_t wakeState = BT_VND_LPM_WAKE_ASSERT;
381 lib_interface_->op(BT_VND_OP_LPM_WAKE_SET_STATE, &wakeState);
382 ALOGV("%s: Sent wake before (%02x)", __func__, data[0] | (data[1] << 8));
383 }
Myles Watsonbeb13b42017-01-26 10:47:27 -0800384
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800385 return hci_ ? hci_->Send(type, data, length) : 0;
386 } // vendor_mutex_ done
Andre Eisenbach89ba5282016-10-13 15:45:02 -0700387}
388
389void VendorInterface::OnFirmwareConfigured(uint8_t result) {
Andre Eisenbach9041d972017-01-17 18:23:12 -0800390 ALOGD("%s result: %d", __func__, result);
Andre Eisenbach9041d972017-01-17 18:23:12 -0800391
392 if (firmware_startup_timer_ != nullptr) {
393 delete firmware_startup_timer_;
394 firmware_startup_timer_ = nullptr;
395 }
396
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800397 {
398 std::unique_lock<std::mutex> guard(initcb_mutex_);
399 ALOGD("%s OnFirmwareConfigured get lock", __func__);
400 if (initialize_complete_cb_ != nullptr) {
401 LOG_ALWAYS_FATAL_IF((result != 0),
402 "%s: Failed to init firmware!", __func__);
403 initialize_complete_cb_(result == 0);
404 }
405 } // initcb_mutex_ done
406
407 if (lib_interface_ != nullptr) {
408 lib_interface_->op(BT_VND_OP_GET_LPM_IDLE_TIMEOUT, &lpm_timeout_ms);
409 ALOGI("%s: lpm_timeout_ms %d", __func__, lpm_timeout_ms);
410
411 bt_vendor_lpm_mode_t mode = BT_VND_LPM_ENABLE;
412 lib_interface_->op(BT_VND_OP_LPM_SET_MODE, &mode);
413
414 ALOGD("%s Calling StartLowPowerWatchdog()", __func__);
415 fd_watcher_.ConfigureTimeout(std::chrono::milliseconds(lpm_timeout_ms),
416 [this]() { OnTimeout(); });
417 }
418 else {
419 ALOGE("lib_interface_ is null");
Andre Eisenbach9041d972017-01-17 18:23:12 -0800420 }
Myles Watsonbeb13b42017-01-26 10:47:27 -0800421
xiaoshun.xu1adfae92022-09-14 20:39:16 +0800422 initialize_complete_cb_ = nullptr;
Myles Watsonbeb13b42017-01-26 10:47:27 -0800423}
424
425void VendorInterface::OnTimeout() {
426 ALOGV("%s", __func__);
427 if (recent_activity_flag == false) {
428 lpm_wake_deasserted = true;
429 bt_vendor_lpm_wake_state_t wakeState = BT_VND_LPM_WAKE_DEASSERT;
430 lib_interface_->op(BT_VND_OP_LPM_WAKE_SET_STATE, &wakeState);
431 fd_watcher_.ConfigureTimeout(std::chrono::seconds(0), []() {
432 ALOGE("Zero timeout! Should never happen.");
433 });
434 }
435 recent_activity_flag = false;
Andre Eisenbach89ba5282016-10-13 15:45:02 -0700436}
437
Zach Johnson917efb12017-02-26 23:46:05 -0800438void VendorInterface::HandleIncomingEvent(const hidl_vec<uint8_t>& hci_packet) {
439 if (internal_command.cb != nullptr &&
440 internal_command_event_match(hci_packet)) {
441 HC_BT_HDR* bt_hdr = WrapPacketAndCopy(HCI_PACKET_TYPE_EVENT, hci_packet);
Andre Eisenbach89ba5282016-10-13 15:45:02 -0700442
Zach Johnson917efb12017-02-26 23:46:05 -0800443 // The callbacks can send new commands, so don't zero after calling.
444 tINT_CMD_CBACK saved_cb = internal_command.cb;
445 internal_command.cb = nullptr;
446 saved_cb(bt_hdr);
447 } else {
448 event_cb_(hci_packet);
449 }
Andre Eisenbach89ba5282016-10-13 15:45:02 -0700450}
451
452} // namespace implementation
453} // namespace V1_0
454} // namespace bluetooth
455} // namespace hardware
456} // namespace android