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