1 /******************************************************************************
2 *
3 * Copyright (C) 2014 Google, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 #define LOG_TAG "bt_hci"
20
21 #include "hci_layer.h"
22
23 #include <base/bind.h>
24 #include <base/logging.h>
25 #include <base/run_loop.h>
26 #include <base/sequenced_task_runner.h>
27 #include <base/threading/thread.h>
28
29 #include <signal.h>
30 #include <string.h>
31 #include <sys/types.h>
32 #include <unistd.h>
33
34 #include <chrono>
35 #include <mutex>
36
37 #include "btcore/include/module.h"
38 #include "btsnoop.h"
39 #include "buffer_allocator.h"
40 #include "hci_inject.h"
41 #include "hci_internals.h"
42 #include "hcidefs.h"
43 #include "hcimsgs.h"
44 #include "osi/include/alarm.h"
45 #include "osi/include/list.h"
46 #include "osi/include/log.h"
47 #include "osi/include/properties.h"
48 #include "osi/include/reactor.h"
49 #include "packet_fragmenter.h"
50
51 #define BT_HCI_TIMEOUT_TAG_NUM 1010000
52
53 extern void hci_initialize();
54 extern void hci_transmit(BT_HDR* packet);
55 extern void hci_close();
56 extern int hci_open_firmware_log_file();
57 extern void hci_close_firmware_log_file(int fd);
58 extern void hci_log_firmware_debug_packet(int fd, BT_HDR* packet);
59
60 static int hci_firmware_log_fd = INVALID_FD;
61
62 typedef struct {
63 uint16_t opcode;
64 future_t* complete_future;
65 command_complete_cb complete_callback;
66 command_status_cb status_callback;
67 void* context;
68 BT_HDR* command;
69 std::chrono::time_point<std::chrono::steady_clock> timestamp;
70 } waiting_command_t;
71
72 // Using a define here, because it can be stringified for the property lookup
73 #define DEFAULT_STARTUP_TIMEOUT_MS 8000
74 #define STRING_VALUE_OF(x) #x
75
76 // RT priority for HCI thread
77 static const int BT_HCI_RT_PRIORITY = 1;
78
79 // Abort if there is no response to an HCI command.
80 static const uint32_t COMMAND_PENDING_TIMEOUT_MS = 2000;
81 static const uint32_t COMMAND_TIMEOUT_RESTART_US = 500000;
82
83 // Our interface
84 static bool interface_created;
85 static hci_t interface;
86
87 // Modules we import and callbacks we export
88 static const allocator_t* buffer_allocator;
89 static const btsnoop_t* btsnoop;
90 static const packet_fragmenter_t* packet_fragmenter;
91
92 static future_t* startup_future;
93 static thread_t* thread; // We own this
94 static std::mutex message_loop_mutex;
95 static base::MessageLoop* message_loop_ = nullptr;
96 static base::RunLoop* run_loop_ = nullptr;
97
98 static alarm_t* startup_timer;
99
100 // Outbound-related
101 static int command_credits = 1;
102 static std::mutex command_credits_mutex;
103 static std::queue<base::Closure> command_queue;
104
105 // Inbound-related
106 static alarm_t* command_response_timer;
107 static list_t* commands_pending_response;
108 static std::recursive_mutex commands_pending_response_mutex;
109
110 // The hand-off point for data going to a higher layer, set by the higher layer
111 static fixed_queue_t* upwards_data_queue;
112
113 static bool filter_incoming_event(BT_HDR* packet);
114 static waiting_command_t* get_waiting_command(command_opcode_t opcode);
115 static int get_num_waiting_commands();
116
117 static void event_finish_startup(void* context);
118 static void startup_timer_expired(void* context);
119
120 static void enqueue_command(waiting_command_t* wait_entry);
121 static void event_command_ready(waiting_command_t* wait_entry);
122 static void enqueue_packet(void* packet);
123 static void event_packet_ready(void* packet);
124 static void command_timed_out(void* context);
125
126 static void update_command_response_timer(void);
127
128 static void transmit_fragment(BT_HDR* packet, bool send_transmit_finished);
129 static void dispatch_reassembled(BT_HDR* packet);
130 static void fragmenter_transmit_finished(BT_HDR* packet,
131 bool all_fragments_sent);
132
133 static const packet_fragmenter_callbacks_t packet_fragmenter_callbacks = {
134 transmit_fragment, dispatch_reassembled, fragmenter_transmit_finished};
135
initialization_complete()136 void initialization_complete() {
137 std::lock_guard<std::mutex> lock(message_loop_mutex);
138 message_loop_->task_runner()->PostTask(
139 FROM_HERE, base::Bind(&event_finish_startup, nullptr));
140 }
141
hci_event_received(BT_HDR * packet)142 void hci_event_received(BT_HDR* packet) {
143 btsnoop->capture(packet, true);
144
145 if (!filter_incoming_event(packet)) {
146 data_dispatcher_dispatch(interface.event_dispatcher, packet->data[0],
147 packet);
148 }
149 }
150
acl_event_received(BT_HDR * packet)151 void acl_event_received(BT_HDR* packet) {
152 btsnoop->capture(packet, true);
153 packet_fragmenter->reassemble_and_dispatch(packet);
154 }
155
sco_data_received(BT_HDR * packet)156 void sco_data_received(BT_HDR* packet) {
157 btsnoop->capture(packet, true);
158 packet_fragmenter->reassemble_and_dispatch(packet);
159 }
160
161 // Module lifecycle functions
162
163 static future_t* hci_module_shut_down();
164
message_loop_run(UNUSED_ATTR void * context)165 void message_loop_run(UNUSED_ATTR void* context) {
166 {
167 std::lock_guard<std::mutex> lock(message_loop_mutex);
168 message_loop_ = new base::MessageLoop();
169 run_loop_ = new base::RunLoop();
170 }
171
172 message_loop_->task_runner()->PostTask(FROM_HERE,
173 base::Bind(&hci_initialize));
174 run_loop_->Run();
175
176 {
177 std::lock_guard<std::mutex> lock(message_loop_mutex);
178 delete message_loop_;
179 message_loop_ = nullptr;
180 delete run_loop_;
181 run_loop_ = nullptr;
182 }
183 }
184
hci_module_start_up(void)185 static future_t* hci_module_start_up(void) {
186 LOG_INFO(LOG_TAG, "%s", __func__);
187
188 // The host is only allowed to send at most one command initially,
189 // as per the Bluetooth spec, Volume 2, Part E, 4.4 (Command Flow Control)
190 // This value can change when you get a command complete or command status
191 // event.
192 command_credits = 1;
193
194 // For now, always use the default timeout on non-Android builds.
195 period_ms_t startup_timeout_ms = DEFAULT_STARTUP_TIMEOUT_MS;
196
197 // Grab the override startup timeout ms, if present.
198 char timeout_prop[PROPERTY_VALUE_MAX];
199 if (!osi_property_get("bluetooth.enable_timeout_ms", timeout_prop,
200 STRING_VALUE_OF(DEFAULT_STARTUP_TIMEOUT_MS)) ||
201 (startup_timeout_ms = atoi(timeout_prop)) < 100)
202 startup_timeout_ms = DEFAULT_STARTUP_TIMEOUT_MS;
203
204 startup_timer = alarm_new("hci.startup_timer");
205 if (!startup_timer) {
206 LOG_ERROR(LOG_TAG, "%s unable to create startup timer.", __func__);
207 goto error;
208 }
209
210 command_response_timer = alarm_new("hci.command_response_timer");
211 if (!command_response_timer) {
212 LOG_ERROR(LOG_TAG, "%s unable to create command response timer.", __func__);
213 goto error;
214 }
215
216 thread = thread_new("hci_thread");
217 if (!thread) {
218 LOG_ERROR(LOG_TAG, "%s unable to create thread.", __func__);
219 goto error;
220 }
221 if (!thread_set_rt_priority(thread, BT_HCI_RT_PRIORITY)) {
222 LOG_ERROR(LOG_TAG, "%s unable to make thread RT.", __func__);
223 }
224
225 commands_pending_response = list_new(NULL);
226 if (!commands_pending_response) {
227 LOG_ERROR(LOG_TAG,
228 "%s unable to create list for commands pending response.",
229 __func__);
230 goto error;
231 }
232
233 // Make sure we run in a bounded amount of time
234 future_t* local_startup_future;
235 local_startup_future = future_new();
236 startup_future = local_startup_future;
237 alarm_set(startup_timer, startup_timeout_ms, startup_timer_expired, NULL);
238
239 packet_fragmenter->init(&packet_fragmenter_callbacks);
240
241 thread_post(thread, message_loop_run, NULL);
242
243 LOG_DEBUG(LOG_TAG, "%s starting async portion", __func__);
244 return local_startup_future;
245
246 error:
247 hci_module_shut_down(); // returns NULL so no need to wait for it
248 return future_new_immediate(FUTURE_FAIL);
249 }
250
hci_module_shut_down()251 static future_t* hci_module_shut_down() {
252 LOG_INFO(LOG_TAG, "%s", __func__);
253
254 // Free the timers
255 {
256 std::lock_guard<std::recursive_mutex> lock(commands_pending_response_mutex);
257 alarm_free(command_response_timer);
258 command_response_timer = NULL;
259 alarm_free(startup_timer);
260 startup_timer = NULL;
261 }
262
263 {
264 std::lock_guard<std::mutex> lock(message_loop_mutex);
265 message_loop_->task_runner()->PostTask(FROM_HERE, run_loop_->QuitClosure());
266 }
267
268 // Stop the thread to prevent Send() calls.
269 if (thread) {
270 thread_stop(thread);
271 thread_join(thread);
272 }
273
274 // Close HCI to prevent callbacks.
275 hci_close();
276
277 {
278 std::lock_guard<std::recursive_mutex> lock(commands_pending_response_mutex);
279 list_free(commands_pending_response);
280 commands_pending_response = NULL;
281 }
282
283 packet_fragmenter->cleanup();
284
285 thread_free(thread);
286 thread = NULL;
287
288 return NULL;
289 }
290
291 EXPORT_SYMBOL extern const module_t hci_module = {
292 .name = HCI_MODULE,
293 .init = NULL,
294 .start_up = hci_module_start_up,
295 .shut_down = hci_module_shut_down,
296 .clean_up = NULL,
297 .dependencies = {BTSNOOP_MODULE, NULL}};
298
299 // Interface functions
300
set_data_queue(fixed_queue_t * queue)301 static void set_data_queue(fixed_queue_t* queue) { upwards_data_queue = queue; }
302
transmit_command(BT_HDR * command,command_complete_cb complete_callback,command_status_cb status_callback,void * context)303 static void transmit_command(BT_HDR* command,
304 command_complete_cb complete_callback,
305 command_status_cb status_callback, void* context) {
306 waiting_command_t* wait_entry = reinterpret_cast<waiting_command_t*>(
307 osi_calloc(sizeof(waiting_command_t)));
308
309 uint8_t* stream = command->data + command->offset;
310 STREAM_TO_UINT16(wait_entry->opcode, stream);
311 wait_entry->complete_callback = complete_callback;
312 wait_entry->status_callback = status_callback;
313 wait_entry->command = command;
314 wait_entry->context = context;
315
316 // Store the command message type in the event field
317 // in case the upper layer didn't already
318 command->event = MSG_STACK_TO_HC_HCI_CMD;
319
320 enqueue_command(wait_entry);
321 }
322
transmit_command_futured(BT_HDR * command)323 static future_t* transmit_command_futured(BT_HDR* command) {
324 waiting_command_t* wait_entry = reinterpret_cast<waiting_command_t*>(
325 osi_calloc(sizeof(waiting_command_t)));
326 future_t* future = future_new();
327
328 uint8_t* stream = command->data + command->offset;
329 STREAM_TO_UINT16(wait_entry->opcode, stream);
330 wait_entry->complete_future = future;
331 wait_entry->command = command;
332
333 // Store the command message type in the event field
334 // in case the upper layer didn't already
335 command->event = MSG_STACK_TO_HC_HCI_CMD;
336
337 enqueue_command(wait_entry);
338 return future;
339 }
340
transmit_downward(data_dispatcher_type_t type,void * data)341 static void transmit_downward(data_dispatcher_type_t type, void* data) {
342 if (type == MSG_STACK_TO_HC_HCI_CMD) {
343 // TODO(zachoverflow): eliminate this call
344 transmit_command((BT_HDR*)data, NULL, NULL, NULL);
345 LOG_WARN(LOG_TAG,
346 "%s legacy transmit of command. Use transmit_command instead.",
347 __func__);
348 } else {
349 enqueue_packet(data);
350 }
351 }
352
353 // Start up functions
354
event_finish_startup(UNUSED_ATTR void * context)355 static void event_finish_startup(UNUSED_ATTR void* context) {
356 LOG_INFO(LOG_TAG, "%s", __func__);
357 std::lock_guard<std::recursive_mutex> lock(commands_pending_response_mutex);
358 alarm_cancel(startup_timer);
359 future_ready(startup_future, FUTURE_SUCCESS);
360 startup_future = NULL;
361 }
362
startup_timer_expired(UNUSED_ATTR void * context)363 static void startup_timer_expired(UNUSED_ATTR void* context) {
364 LOG_ERROR(LOG_TAG, "%s", __func__);
365
366 std::lock_guard<std::recursive_mutex> lock(commands_pending_response_mutex);
367 future_ready(startup_future, FUTURE_FAIL);
368 startup_future = NULL;
369 }
370
371 // Command/packet transmitting functions
enqueue_command(waiting_command_t * wait_entry)372 static void enqueue_command(waiting_command_t* wait_entry) {
373 base::Closure callback = base::Bind(&event_command_ready, wait_entry);
374
375 std::lock_guard<std::mutex> command_credits_lock(command_credits_mutex);
376 if (command_credits > 0) {
377 std::lock_guard<std::mutex> message_loop_lock(message_loop_mutex);
378 if (message_loop_ == nullptr) {
379 // HCI Layer was shut down
380 buffer_allocator->free(wait_entry->command);
381 osi_free(wait_entry);
382 return;
383 }
384 message_loop_->task_runner()->PostTask(FROM_HERE, std::move(callback));
385 command_credits--;
386 } else {
387 command_queue.push(std::move(callback));
388 }
389 }
390
event_command_ready(waiting_command_t * wait_entry)391 static void event_command_ready(waiting_command_t* wait_entry) {
392 /// Move it to the list of commands awaiting response
393 std::lock_guard<std::recursive_mutex> lock(commands_pending_response_mutex);
394 wait_entry->timestamp = std::chrono::steady_clock::now();
395 list_append(commands_pending_response, wait_entry);
396
397 // Send it off
398 packet_fragmenter->fragment_and_dispatch(wait_entry->command);
399
400 update_command_response_timer();
401 }
402
enqueue_packet(void * packet)403 static void enqueue_packet(void* packet) {
404 std::lock_guard<std::mutex> lock(message_loop_mutex);
405 if (message_loop_ == nullptr) {
406 // HCI Layer was shut down
407 buffer_allocator->free(packet);
408 return;
409 }
410 message_loop_->task_runner()->PostTask(
411 FROM_HERE, base::Bind(&event_packet_ready, packet));
412 }
413
event_packet_ready(void * pkt)414 static void event_packet_ready(void* pkt) {
415 // The queue may be the command queue or the packet queue, we don't care
416 BT_HDR* packet = (BT_HDR*)pkt;
417 packet_fragmenter->fragment_and_dispatch(packet);
418 }
419
420 // Callback for the fragmenter to send a fragment
transmit_fragment(BT_HDR * packet,bool send_transmit_finished)421 static void transmit_fragment(BT_HDR* packet, bool send_transmit_finished) {
422 btsnoop->capture(packet, false);
423
424 hci_transmit(packet);
425
426 uint16_t event = packet->event & MSG_EVT_MASK;
427 if (event != MSG_STACK_TO_HC_HCI_CMD && send_transmit_finished)
428 buffer_allocator->free(packet);
429 }
430
fragmenter_transmit_finished(BT_HDR * packet,bool all_fragments_sent)431 static void fragmenter_transmit_finished(BT_HDR* packet,
432 bool all_fragments_sent) {
433 if (all_fragments_sent) {
434 buffer_allocator->free(packet);
435 } else {
436 // This is kind of a weird case, since we're dispatching a partially sent
437 // packet up to a higher layer.
438 // TODO(zachoverflow): rework upper layer so this isn't necessary.
439 data_dispatcher_dispatch(interface.event_dispatcher,
440 packet->event & MSG_EVT_MASK, packet);
441 }
442 }
443
444 // Print debugging information and quit. Don't dereference original_wait_entry.
command_timed_out(void * original_wait_entry)445 static void command_timed_out(void* original_wait_entry) {
446 std::unique_lock<std::recursive_mutex> lock(commands_pending_response_mutex);
447
448 LOG_ERROR(LOG_TAG, "%s: %d commands pending response", __func__,
449 get_num_waiting_commands());
450
451 for (const list_node_t* node = list_begin(commands_pending_response);
452 node != list_end(commands_pending_response); node = list_next(node)) {
453 waiting_command_t* wait_entry =
454 reinterpret_cast<waiting_command_t*>(list_node(node));
455
456 int wait_time_ms =
457 std::chrono::duration_cast<std::chrono::milliseconds>(
458 std::chrono::steady_clock::now() - wait_entry->timestamp)
459 .count();
460 LOG_ERROR(LOG_TAG, "%s: Waited %d ms for a response to opcode: 0x%x %s",
461 __func__, wait_time_ms, wait_entry->opcode,
462 (wait_entry == original_wait_entry) ? "*matches timer*" : "");
463
464 // Dump the length field and the first byte of the payload, if present.
465 uint8_t* command = wait_entry->command->data + wait_entry->command->offset;
466 if (wait_entry->command->len > 3) {
467 LOG_ERROR(LOG_TAG, "%s: Size %d Hex %02x %02x %02x %02x", __func__,
468 wait_entry->command->len, command[0], command[1], command[2],
469 command[3]);
470 } else {
471 LOG_ERROR(LOG_TAG, "%s: Size %d Hex %02x %02x %02x", __func__,
472 wait_entry->command->len, command[0], command[1], command[2]);
473 }
474
475 LOG_EVENT_INT(BT_HCI_TIMEOUT_TAG_NUM, wait_entry->opcode);
476 }
477 lock.unlock();
478
479 LOG_ERROR(LOG_TAG, "%s: requesting a firmware dump.", __func__);
480
481 /* Allocate a buffer to hold the HCI command. */
482 BT_HDR* bt_hdr =
483 static_cast<BT_HDR*>(osi_malloc(sizeof(BT_HDR) + HCIC_PREAMBLE_SIZE));
484
485 bt_hdr->len = HCIC_PREAMBLE_SIZE;
486 bt_hdr->event = MSG_STACK_TO_HC_HCI_CMD;
487 bt_hdr->offset = 0;
488
489 uint8_t* hci_packet = reinterpret_cast<uint8_t*>(bt_hdr + 1);
490
491 UINT16_TO_STREAM(hci_packet,
492 HCI_GRP_VENDOR_SPECIFIC | HCI_CONTROLLER_DEBUG_INFO_OCF);
493 UINT8_TO_STREAM(hci_packet, 0); // No parameters
494
495 hci_firmware_log_fd = hci_open_firmware_log_file();
496
497 transmit_fragment(bt_hdr, true);
498
499 osi_free(bt_hdr);
500
501 LOG_ERROR(LOG_TAG, "%s restarting the Bluetooth process.", __func__);
502 usleep(COMMAND_TIMEOUT_RESTART_US);
503 hci_close_firmware_log_file(hci_firmware_log_fd);
504
505 // We shouldn't try to recover the stack from this command timeout.
506 // If it's caused by a software bug, fix it. If it's a hardware bug, fix it.
507 abort();
508 }
509
510 // Event/packet receiving functions
process_command_credits(int credits)511 void process_command_credits(int credits) {
512 std::lock_guard<std::mutex> command_credits_lock(command_credits_mutex);
513 std::lock_guard<std::mutex> message_loop_lock(message_loop_mutex);
514
515 if (message_loop_ == nullptr) {
516 // HCI Layer was shut down
517 return;
518 }
519
520 // Subtract commands in flight.
521 command_credits = credits - get_num_waiting_commands();
522
523 while (command_credits > 0 && command_queue.size() > 0) {
524 message_loop_->task_runner()->PostTask(FROM_HERE,
525 std::move(command_queue.front()));
526 command_queue.pop();
527 command_credits--;
528 }
529 }
530
531 // Returns true if the event was intercepted and should not proceed to
532 // higher layers. Also inspects an incoming event for interesting
533 // information, like how many commands are now able to be sent.
filter_incoming_event(BT_HDR * packet)534 static bool filter_incoming_event(BT_HDR* packet) {
535 waiting_command_t* wait_entry = NULL;
536 uint8_t* stream = packet->data;
537 uint8_t event_code;
538 int credits = 0;
539 command_opcode_t opcode;
540
541 STREAM_TO_UINT8(event_code, stream);
542 STREAM_SKIP_UINT8(stream); // Skip the parameter total length field
543
544 if (event_code == HCI_COMMAND_COMPLETE_EVT) {
545 STREAM_TO_UINT8(credits, stream);
546 STREAM_TO_UINT16(opcode, stream);
547
548 wait_entry = get_waiting_command(opcode);
549
550 process_command_credits(credits);
551
552 if (!wait_entry) {
553 if (opcode != HCI_COMMAND_NONE) {
554 LOG_WARN(LOG_TAG,
555 "%s command complete event with no matching command (opcode: "
556 "0x%04x).",
557 __func__, opcode);
558 }
559 } else {
560 update_command_response_timer();
561 if (wait_entry->complete_callback) {
562 wait_entry->complete_callback(packet, wait_entry->context);
563 } else if (wait_entry->complete_future) {
564 future_ready(wait_entry->complete_future, packet);
565 }
566 }
567
568 goto intercepted;
569 } else if (event_code == HCI_COMMAND_STATUS_EVT) {
570 uint8_t status;
571 STREAM_TO_UINT8(status, stream);
572 STREAM_TO_UINT8(credits, stream);
573 STREAM_TO_UINT16(opcode, stream);
574
575 // If a command generates a command status event, it won't be getting a
576 // command complete event
577 wait_entry = get_waiting_command(opcode);
578
579 process_command_credits(credits);
580
581 if (!wait_entry) {
582 LOG_WARN(
583 LOG_TAG,
584 "%s command status event with no matching command. opcode: 0x%04x",
585 __func__, opcode);
586 } else {
587 update_command_response_timer();
588 if (wait_entry->status_callback)
589 wait_entry->status_callback(status, wait_entry->command,
590 wait_entry->context);
591 }
592
593 goto intercepted;
594 } else if (event_code == HCI_VSE_SUBCODE_DEBUG_INFO_SUB_EVT) {
595 if (hci_firmware_log_fd == INVALID_FD)
596 hci_firmware_log_fd = hci_open_firmware_log_file();
597
598 if (hci_firmware_log_fd != INVALID_FD)
599 hci_log_firmware_debug_packet(hci_firmware_log_fd, packet);
600
601 buffer_allocator->free(packet);
602 return true;
603 }
604
605 return false;
606
607 intercepted:
608 if (wait_entry) {
609 // If it has a callback, it's responsible for freeing the packet
610 if (event_code == HCI_COMMAND_STATUS_EVT ||
611 (!wait_entry->complete_callback && !wait_entry->complete_future))
612 buffer_allocator->free(packet);
613
614 // If it has a callback, it's responsible for freeing the command
615 if (event_code == HCI_COMMAND_COMPLETE_EVT || !wait_entry->status_callback)
616 buffer_allocator->free(wait_entry->command);
617
618 osi_free(wait_entry);
619 } else {
620 buffer_allocator->free(packet);
621 }
622
623 return true;
624 }
625
626 // Callback for the fragmenter to dispatch up a completely reassembled packet
dispatch_reassembled(BT_HDR * packet)627 static void dispatch_reassembled(BT_HDR* packet) {
628 // Events should already have been dispatched before this point
629 CHECK((packet->event & MSG_EVT_MASK) != MSG_HC_TO_STACK_HCI_EVT);
630 CHECK(upwards_data_queue != NULL);
631
632 fixed_queue_enqueue(upwards_data_queue, packet);
633 }
634
635 // Misc internal functions
636
get_waiting_command(command_opcode_t opcode)637 static waiting_command_t* get_waiting_command(command_opcode_t opcode) {
638 std::lock_guard<std::recursive_mutex> lock(commands_pending_response_mutex);
639
640 for (const list_node_t* node = list_begin(commands_pending_response);
641 node != list_end(commands_pending_response); node = list_next(node)) {
642 waiting_command_t* wait_entry =
643 reinterpret_cast<waiting_command_t*>(list_node(node));
644
645 if (!wait_entry || wait_entry->opcode != opcode) continue;
646
647 list_remove(commands_pending_response, wait_entry);
648
649 return wait_entry;
650 }
651
652 return NULL;
653 }
654
get_num_waiting_commands()655 static int get_num_waiting_commands() {
656 std::lock_guard<std::recursive_mutex> lock(commands_pending_response_mutex);
657 return list_length(commands_pending_response);
658 }
659
update_command_response_timer(void)660 static void update_command_response_timer(void) {
661 std::lock_guard<std::recursive_mutex> lock(commands_pending_response_mutex);
662
663 if (command_response_timer == NULL) return;
664 if (list_is_empty(commands_pending_response)) {
665 alarm_cancel(command_response_timer);
666 } else {
667 alarm_set(command_response_timer, COMMAND_PENDING_TIMEOUT_MS,
668 command_timed_out, list_front(commands_pending_response));
669 }
670 }
671
init_layer_interface()672 static void init_layer_interface() {
673 if (!interface_created) {
674 // It's probably ok for this to live forever. It's small and
675 // there's only one instance of the hci interface.
676 interface.event_dispatcher = data_dispatcher_new("hci_layer");
677 if (!interface.event_dispatcher) {
678 LOG_ERROR(LOG_TAG, "%s could not create upward dispatcher.", __func__);
679 return;
680 }
681
682 interface.set_data_queue = set_data_queue;
683 interface.transmit_command = transmit_command;
684 interface.transmit_command_futured = transmit_command_futured;
685 interface.transmit_downward = transmit_downward;
686 interface_created = true;
687 }
688 }
689
hci_layer_cleanup_interface()690 void hci_layer_cleanup_interface() {
691 if (interface_created) {
692 data_dispatcher_free(interface.event_dispatcher);
693 interface.event_dispatcher = NULL;
694
695 interface.set_data_queue = NULL;
696 interface.transmit_command = NULL;
697 interface.transmit_command_futured = NULL;
698 interface.transmit_downward = NULL;
699 interface_created = false;
700 }
701 }
702
hci_layer_get_interface()703 const hci_t* hci_layer_get_interface() {
704 buffer_allocator = buffer_allocator_get_interface();
705 btsnoop = btsnoop_get_interface();
706 packet_fragmenter = packet_fragmenter_get_interface();
707
708 init_layer_interface();
709
710 return &interface;
711 }
712
hci_layer_get_test_interface(const allocator_t * buffer_allocator_interface,const btsnoop_t * btsnoop_interface,const packet_fragmenter_t * packet_fragmenter_interface)713 const hci_t* hci_layer_get_test_interface(
714 const allocator_t* buffer_allocator_interface,
715 const btsnoop_t* btsnoop_interface,
716 const packet_fragmenter_t* packet_fragmenter_interface) {
717 buffer_allocator = buffer_allocator_interface;
718 btsnoop = btsnoop_interface;
719 packet_fragmenter = packet_fragmenter_interface;
720
721 init_layer_interface();
722 return &interface;
723 }
724