OSDN Git Service

Refactor bte_main into more of a shell.
authorZach Johnson <zachoverflow@google.com>
Tue, 9 Sep 2014 01:31:39 +0000 (18:31 -0700)
committerAndre Eisenbach <eisenbach@google.com>
Mon, 16 Mar 2015 23:51:33 +0000 (16:51 -0700)
Moves all HCI initialization into hci_layer. Removes superfluous exposed
functionality on the HCI layer (like turning the chip on/off and logging)

Also reorganizes some of hci_layer to group related functions together.

hci/Android.mk
hci/include/btsnoop.h
hci/include/hci_layer.h
hci/src/btsnoop.c
hci/src/hci_layer.c
hci/test/hci_layer_test.cpp
main/bte_main.c

index 3c233e2..190abcc 100644 (file)
@@ -72,6 +72,6 @@ LOCAL_CFLAGS := -Wall -Werror $(bdroid_CFLAGS)
 LOCAL_MODULE := libbt-hcitests
 LOCAL_MODULE_TAGS := tests
 LOCAL_SHARED_LIBRARIES := liblog libdl
-LOCAL_STATIC_LIBRARIES := libbt-hci libosi
+LOCAL_STATIC_LIBRARIES := libbt-hci libosi libcutils
 
 include $(BUILD_NATIVE_TEST)
index 8c21cd1..05ff791 100644 (file)
 #include "bt_types.h"
 
 typedef struct btsnoop_t {
-  // Open btsnoop, and dump captured packets to the file pointed to by |path|.
-  void (*open)(const char *path);
+  // Sets the logging path for btsnoop to the provided |path|.
+  void (*set_logging_path)(const char *path);
 
-  // Close btsnoop, so no more packets are captured.
-  void (*close)(void);
+  // Turns btsnoop logging on or off, depending on |value|. If
+  // you are turning btsnoop on, you must have set a logging path.
+  void (*set_is_running)(bool value);
 
   // Capture |packet| and dump it to the btsnoop logs. If |is_received| is
   // true, the packet is marked as incoming. Otherwise, the packet is marked
index 9ba6238..ba674ba 100644 (file)
@@ -66,14 +66,14 @@ typedef enum {
   LPM_WAKE_DEASSERT
 } low_power_command_t;
 
-typedef void (*preload_finished_cb)(bool success);
+typedef void (*startup_finished_cb)(bool success);
 typedef void (*transmit_finished_cb)(void *buffer, bool all_fragments_sent);
 typedef void (*command_complete_cb)(BT_HDR *response, void *context);
 typedef void (*command_status_cb)(uint8_t status, BT_HDR *command, void *context);
 
 typedef struct {
   // Called when the HCI layer finishes the preload sequence.
-  preload_finished_cb preload_finished;
+  startup_finished_cb startup_finished;
 
   // Called when the HCI layer finishes sending a packet.
   transmit_finished_cb transmit_finished;
@@ -81,7 +81,9 @@ typedef struct {
 
 typedef struct hci_t {
   // Start up the HCI layer, with the specified |local_bdaddr|.
-  bool (*start_up)(
+  // |upper_callbacks->startup_finished| will be called when the full
+  // start up sequence is complete.
+  bool (*start_up_async)(
       bdaddr_t local_bdaddr,
       const hci_callbacks_t *upper_callbacks
   );
@@ -89,23 +91,12 @@ typedef struct hci_t {
   // Tear down and relese all resources
   void (*shut_down)(void);
 
-  // Turn the Bluetooth chip on or off, depending on |value|.
-  void (*set_chip_power_on)(bool value);
-
   // Send a low power command, if supported and the low power manager is enabled.
   void (*send_low_power_command)(low_power_command_t command);
 
-  // Do the preload sequence (call before the rest of the BT stack initializes).
-  void (*do_preload)(void);
-
   // Do the postload sequence (call after the rest of the BT stack initializes).
   void (*do_postload)(void);
 
-  // Turn logging on, and log to the specified |path|.
-  void (*turn_on_logging)(const char *path);
-
-  void (*turn_off_logging)(void);
-
   // Register with this data dispatcher to receive data flowing upward out of the HCI layer
   data_dispatcher_t *upward_dispatcher;
 
index 3bd5ef4..c16e26c 100644 (file)
@@ -49,6 +49,8 @@ static const uint64_t BTSNOOP_EPOCH_DELTA = 0x00dcddb30f2f8000ULL;
 
 // File descriptor for btsnoop file.
 static int hci_btsnoop_fd = -1;
+static bool is_logging = false;
+static const char *logging_path;
 
 void btsnoop_net_open();
 void btsnoop_net_close();
@@ -147,6 +149,24 @@ static void btsnoop_close(void) {
   btsnoop_net_close();
 }
 
+static void btsnoop_set_logging_path(const char *path) {
+  assert(!is_logging);
+  logging_path = path;
+}
+
+static void btsnoop_set_is_running(bool should_log) {
+  if (should_log == is_logging)
+    return;
+
+  is_logging = should_log;
+  if (should_log) {
+    assert(logging_path != NULL);
+    btsnoop_open(logging_path);
+  } else {
+    btsnoop_close();
+  }
+}
+
 static void btsnoop_capture(const BT_HDR *buffer, bool is_received) {
   const uint8_t *p = buffer->data + buffer->offset;
 
@@ -172,8 +192,8 @@ static void btsnoop_capture(const BT_HDR *buffer, bool is_received) {
 }
 
 static const btsnoop_t interface = {
-  btsnoop_open,
-  btsnoop_close,
+  btsnoop_set_logging_path,
+  btsnoop_set_is_running,
   btsnoop_capture
 };
 
index 171d18b..60450b5 100644 (file)
@@ -19,6 +19,7 @@
 #define LOG_TAG "hci_layer"
 
 #include <assert.h>
+#include <cutils/properties.h>
 #include <utils/Log.h>
 
 #include "buffer_allocator.h"
@@ -87,6 +88,10 @@ typedef struct {
   BT_HDR *command;
 } waiting_command_t;
 
+// Using a define here, because it can be stringified for the property lookup
+#define DEFAULT_STARTUP_TIMEOUT_MS 3000
+#define STRING_VALUE_OF(x) #x
+
 static const uint32_t EPILOG_TIMEOUT_MS = 3000;
 static const uint32_t COMMAND_PENDING_TIMEOUT = 8000;
 
@@ -112,6 +117,7 @@ static thread_t *thread; // We own this
 static volatile bool firmware_is_configured = false;
 static volatile bool has_shut_down = false;
 static non_repeating_timer_t *epilog_timer;
+static non_repeating_timer_t *startup_timer;
 
 // Outbound-related
 static int command_credits = 1;
@@ -124,7 +130,7 @@ static list_t *commands_pending_response;
 static pthread_mutex_t commands_pending_response_lock;
 static packet_receive_data_t incoming_packets[INBOUND_PACKET_TYPE_COUNT];
 
-static void event_preload(void *context);
+static void event_finish_startup(void *context);
 static void event_postload(void *context);
 static void event_epilog(void *context);
 static void event_command_ready(fixed_queue_t *queue, void *context);
@@ -136,11 +142,12 @@ static void epilog_finished_callback(bool success);
 
 static void command_timed_out(void *context);
 static void hal_says_data_ready(serial_data_type_t type);
-static void epilog_wait_timer_expired(void *context);
+static void startup_timer_expired(void *context);
+static void epilog_timer_expired(void *context);
 
 // Interface functions
 
-static bool start_up(bdaddr_t local_bdaddr, const hci_callbacks_t *upper_callbacks) {
+static bool start_up_async(bdaddr_t local_bdaddr, const hci_callbacks_t *upper_callbacks) {
   assert(local_bdaddr != NULL);
   assert(upper_callbacks != NULL);
 
@@ -155,7 +162,23 @@ static bool start_up(bdaddr_t local_bdaddr, const hci_callbacks_t *upper_callbac
 
   pthread_mutex_init(&commands_pending_response_lock, NULL);
 
-  epilog_timer = non_repeating_timer_new(EPILOG_TIMEOUT_MS, epilog_wait_timer_expired, NULL);
+  // Grab the override startup timeout ms, if present.
+  period_ms_t startup_timeout_ms;
+  char timeout_prop[PROPERTY_VALUE_MAX];
+  if (!property_get("bluetooth.enable_timeout_ms", timeout_prop, STRING_VALUE_OF(DEFAULT_STARTUP_TIMEOUT_MS))
+      || (startup_timeout_ms = atoi(timeout_prop)) < 100)
+    startup_timeout_ms = DEFAULT_STARTUP_TIMEOUT_MS;
+
+  startup_timer = non_repeating_timer_new(startup_timeout_ms, startup_timer_expired, NULL);
+  if (!startup_timer) {
+    ALOGE("%s unable to create startup timer.", __func__);
+    goto error;
+  }
+
+  // Make sure we run in a bounded amount of time
+  non_repeating_timer_restart(startup_timer);
+
+  epilog_timer = non_repeating_timer_new(EPILOG_TIMEOUT_MS, epilog_timer_expired, NULL);
   if (!epilog_timer) {
     ALOGE("%s unable to create epilog timer.", __func__);
     goto error;
@@ -212,6 +235,25 @@ static bool start_up(bdaddr_t local_bdaddr, const hci_callbacks_t *upper_callbac
     // TODO(sharvil): gracefully propagate failures from this layer.
   }
 
+  int power_state = BT_VND_PWR_OFF;
+#if (defined (BT_CLEAN_TURN_ON_DISABLED) && BT_CLEAN_TURN_ON_DISABLED == TRUE)
+  ALOGW("%s not turning off the chip before turning on.", __func__);
+  // So apparently this hack was needed in the past because a Wingray kernel driver
+  // didn't handle power off commands in a powered off state correctly.
+
+  // The comment in the old code said the workaround should be removed when the
+  // problem was fixed. Sadly, I have no idea if said bug was fixed or if said
+  // kernel is still in use, so we must leave this here for posterity. #sadpanda
+#else
+  // cycle power on the chip to ensure it has been reset
+  vendor->send_command(VENDOR_CHIP_POWER_CONTROL, &power_state);
+#endif
+  power_state = BT_VND_PWR_ON;
+  vendor->send_command(VENDOR_CHIP_POWER_CONTROL, &power_state);
+
+  ALOGD("%s starting async portion", __func__);
+  thread_post(thread, event_finish_startup, NULL);
+
   return true;
 error:;
   interface.shut_down();
@@ -249,11 +291,17 @@ static void shut_down() {
 
   non_repeating_timer_free(epilog_timer);
   non_repeating_timer_free(command_response_timer);
+  non_repeating_timer_free(startup_timer);
+
+  epilog_timer = NULL;
+  command_response_timer = NULL;
 
   low_power_manager->cleanup();
   hal->close();
 
-  interface.set_chip_power_on(false);
+  // Turn off the chip
+  int power_state = BT_VND_PWR_OFF;
+  vendor->send_command(VENDOR_CHIP_POWER_CONTROL, &power_state);
   vendor->close();
 
   thread_free(thread);
@@ -262,37 +310,11 @@ static void shut_down() {
   has_shut_down = true;
 }
 
-static void set_chip_power_on(bool value) {
-  ALOGD("%s setting bluetooth chip power on to: %d", __func__, value);
-
-  int power_state = value ? BT_VND_PWR_ON : BT_VND_PWR_OFF;
-  vendor->send_command(VENDOR_CHIP_POWER_CONTROL, &power_state);
-}
-
-static void do_preload() {
-  ALOGD("%s posting preload work item", __func__);
-  thread_post(thread, event_preload, NULL);
-}
-
 static void do_postload() {
   ALOGD("%s posting postload work item", __func__);
   thread_post(thread, event_postload, NULL);
 }
 
-static void turn_on_logging(const char *path) {
-  ALOGD("%s", __func__);
-
-  if (path != NULL)
-    btsnoop->open(path);
-  else
-    ALOGW("%s wanted to start logging, but path was NULL", __func__);
-}
-
-static void turn_off_logging() {
-  ALOGD("%s", __func__);
-  btsnoop->close();
-}
-
 static void transmit_command(
     BT_HDR *command,
     command_complete_cb complete_callback,
@@ -431,34 +453,25 @@ intercepted:;
   return true;
 }
 
-static void on_controller_acl_size_fetch_finished(void) {
-  ALOGI("%s postload finished.", __func__);
-}
+// Start up functions
 
-static void sco_config_callback(UNUSED_ATTR bool success) {
-  controller->begin_acl_size_fetch(on_controller_acl_size_fetch_finished);
+static void event_finish_startup(UNUSED_ATTR void *context) {
+  ALOGI("%s", __func__);
+  hal->open();
+  vendor->send_async_command(VENDOR_CONFIGURE_FIRMWARE, NULL);
 }
 
 static void firmware_config_callback(UNUSED_ATTR bool success) {
   firmware_is_configured = true;
-  callbacks->preload_finished(true);
+  non_repeating_timer_cancel(startup_timer);
+  callbacks->startup_finished(true);
 }
 
-static void epilog_finished_callback(UNUSED_ATTR bool success) {
-  ALOGI("%s", __func__);
-  thread_stop(thread);
+static void startup_timer_expired(UNUSED_ATTR void *context) {
+  callbacks->startup_finished(false);
 }
 
-static void epilog_wait_timer_expired(UNUSED_ATTR void *context) {
-  ALOGI("%s", __func__);
-  thread_stop(thread);
-}
-
-static void event_preload(UNUSED_ATTR void *context) {
-  ALOGI("%s", __func__);
-  hal->open();
-  vendor->send_async_command(VENDOR_CONFIGURE_FIRMWARE, NULL);
-}
+// Postload functions
 
 static void event_postload(UNUSED_ATTR void *context) {
   ALOGI("%s", __func__);
@@ -469,10 +482,30 @@ static void event_postload(UNUSED_ATTR void *context) {
   }
 }
 
+static void on_controller_acl_size_fetch_finished(void) {
+  ALOGI("%s postload finished.", __func__);
+}
+
+static void sco_config_callback(UNUSED_ATTR bool success) {
+  controller->begin_acl_size_fetch(on_controller_acl_size_fetch_finished);
+}
+
+// Epilog functions
+
 static void event_epilog(UNUSED_ATTR void *context) {
   vendor->send_async_command(VENDOR_DO_EPILOG, NULL);
 }
 
+static void epilog_finished_callback(UNUSED_ATTR bool success) {
+  ALOGI("%s", __func__);
+  thread_stop(thread);
+}
+
+static void epilog_timer_expired(UNUSED_ATTR void *context) {
+  ALOGI("%s", __func__);
+  thread_stop(thread);
+}
+
 static void event_command_ready(fixed_queue_t *queue, UNUSED_ATTR void *context) {
   if (command_credits > 0) {
     waiting_command_t *wait_entry = fixed_queue_dequeue(queue);
@@ -627,15 +660,11 @@ static void fragmenter_transmit_finished(void *buffer, bool all_fragments_sent)
 
 static void init_layer_interface() {
   if (!interface_created) {
-    interface.start_up = start_up;
+    interface.start_up_async = start_up_async;
     interface.shut_down = shut_down;
 
-    interface.set_chip_power_on = set_chip_power_on;
     interface.send_low_power_command = low_power_manager->post_command;
-    interface.do_preload = do_preload;
     interface.do_postload = do_postload;
-    interface.turn_on_logging = turn_on_logging;
-    interface.turn_off_logging = turn_off_logging;
 
     // It's probably ok for this to live forever. It's small and
     // there's only one instance of the hci interface.
index cd2c3ba..d040138 100644 (file)
@@ -41,18 +41,14 @@ extern "C" {
 }
 
 DECLARE_TEST_MODES(
-  start_up,
+  start_up_async,
   shut_down,
-  cycle_power,
-  preload,
   postload,
   transmit_simple,
   receive_simple,
   transmit_command_no_callbacks,
   transmit_command_command_status,
   transmit_command_command_complete,
-  turn_on_logging,
-  turn_off_logging
 );
 
 static const char *small_sample_data = "\"It is easy to see,\" replied Don Quixote";
@@ -74,6 +70,18 @@ static int packet_index;
 static unsigned int data_size_sum;
 static BT_HDR *data_to_receive;
 
+static void signal_work_item(UNUSED_ATTR void *context) {
+  semaphore_post(done);
+}
+
+static void flush_thread(thread_t *thread) {
+  // Double flush to ensure we get the next reactor cycle
+  thread_post(thread, signal_work_item, NULL);
+  semaphore_wait(done);
+  thread_post(thread, signal_work_item, NULL);
+  semaphore_wait(done);
+}
+
 // TODO move this to a common packet testing helper
 static BT_HDR *manufacture_packet(uint16_t event, const char *data) {
   uint16_t data_length = strlen(data);
@@ -154,7 +162,7 @@ static void expect_packet(uint16_t event, int max_acl_data_size, const uint8_t *
 }
 
 STUB_FUNCTION(bool, hal_init, (const hci_hal_callbacks_t *callbacks, thread_t *working_thread))
-  DURING(start_up) AT_CALL(0) {
+  DURING(start_up_async) AT_CALL(0) {
     hal_callbacks = callbacks;
     internal_thread = working_thread;
     return true;
@@ -165,7 +173,7 @@ STUB_FUNCTION(bool, hal_init, (const hci_hal_callbacks_t *callbacks, thread_t *w
 }
 
 STUB_FUNCTION(bool, hal_open, ())
-  DURING(preload) AT_CALL(0) return true;
+  DURING(start_up_async) AT_CALL(0) return true;
   UNEXPECTED_CALL;
   return false;
 }
@@ -246,23 +254,9 @@ STUB_FUNCTION(void, hal_packet_finished, (serial_data_type_t type))
   UNEXPECTED_CALL;
 }
 
-STUB_FUNCTION(void, btsnoop_open, (const char *path))
-  DURING(turn_on_logging) AT_CALL(0) {
-    EXPECT_EQ(logging_path, path);
-    return;
-  }
-
-  UNEXPECTED_CALL;
-}
-
-STUB_FUNCTION(void, btsnoop_close, ())
-  DURING(turn_off_logging) AT_CALL(0) return;
-  UNEXPECTED_CALL;
-}
-
 STUB_FUNCTION(bool, hci_inject_open, (
     UNUSED_ATTR const hci_t *hci_interface))
-  DURING(start_up) AT_CALL(0) return true;
+  DURING(start_up_async) AT_CALL(0) return true;
   UNEXPECTED_CALL;
   return false;
 }
@@ -316,7 +310,7 @@ STUB_FUNCTION(void, btsnoop_capture, (const BT_HDR *buffer, bool is_received))
 }
 
 STUB_FUNCTION(void, low_power_init, (UNUSED_ATTR thread_t *thread))
-  DURING(start_up) AT_CALL(0) return;
+  DURING(start_up_async) AT_CALL(0) return;
   UNEXPECTED_CALL;
 }
 
@@ -350,7 +344,7 @@ STUB_FUNCTION(void, low_power_transmit_done, ())
 }
 
 STUB_FUNCTION(bool, vendor_open, (const uint8_t *addr, const hci_t *hci_interface))
-  DURING(start_up) AT_CALL(0) {
+  DURING(start_up_async) AT_CALL(0) {
     EXPECT_EQ(test_addr, addr);
     EXPECT_EQ(hci, hci_interface);
     return true;
@@ -366,7 +360,7 @@ STUB_FUNCTION(void, vendor_close, ())
 }
 
 STUB_FUNCTION(void, vendor_set_callback, (vendor_async_opcode_t opcode, UNUSED_ATTR vendor_cb callback))
-  DURING(start_up) {
+  DURING(start_up_async) {
     AT_CALL(0) {
       EXPECT_EQ(VENDOR_CONFIGURE_FIRMWARE, opcode);
       firmware_config_callback = callback;
@@ -388,32 +382,33 @@ STUB_FUNCTION(void, vendor_set_callback, (vendor_async_opcode_t opcode, UNUSED_A
 }
 
 STUB_FUNCTION(int, vendor_send_command, (vendor_opcode_t opcode, void *param))
-  DURING(shut_down) AT_CALL(0) {
-    EXPECT_EQ(VENDOR_CHIP_POWER_CONTROL, opcode);
-    EXPECT_EQ(BT_VND_PWR_OFF, *(int *)param);
-    return 0;
-  }
-
-  DURING(cycle_power) {
+  DURING(start_up_async) {
     AT_CALL(0) {
       EXPECT_EQ(VENDOR_CHIP_POWER_CONTROL, opcode);
-      EXPECT_EQ(BT_VND_PWR_ON, *(int *)param);
+      EXPECT_EQ(BT_VND_PWR_OFF, *(int *)param);
       return 0;
     }
     AT_CALL(1) {
       EXPECT_EQ(VENDOR_CHIP_POWER_CONTROL, opcode);
-      EXPECT_EQ(BT_VND_PWR_OFF, *(int *)param);
+      EXPECT_EQ(BT_VND_PWR_ON, *(int *)param);
       return 0;
     }
   }
 
+  DURING(shut_down) AT_CALL(0) {
+    EXPECT_EQ(VENDOR_CHIP_POWER_CONTROL, opcode);
+    EXPECT_EQ(BT_VND_PWR_OFF, *(int *)param);
+    return 0;
+  }
+
   UNEXPECTED_CALL;
   return 0;
 }
 
 STUB_FUNCTION(int, vendor_send_async_command, (UNUSED_ATTR vendor_async_opcode_t opcode, UNUSED_ATTR void *param))
-  DURING(preload) AT_CALL(0) {
+  DURING(start_up_async) AT_CALL(0) {
     EXPECT_EQ(VENDOR_CONFIGURE_FIRMWARE, opcode);
+    firmware_config_callback(true);
     return 0;
   }
 
@@ -423,10 +418,26 @@ STUB_FUNCTION(int, vendor_send_async_command, (UNUSED_ATTR vendor_async_opcode_t
     return 0;
   }
 
+  DURING(shut_down) AT_CALL(0) {
+    EXPECT_EQ(VENDOR_DO_EPILOG, opcode);
+    epilog_callback(true);
+    return 0;
+  }
+
   UNEXPECTED_CALL;
   return 0;
 }
 
+STUB_FUNCTION(void, callback_startup_finished, (bool success))
+  DURING(start_up_async) AT_CALL(0) {
+    EXPECT_EQ(true, success);
+    semaphore_post(done);
+    return;
+  }
+
+  UNEXPECTED_CALL;
+}
+
 STUB_FUNCTION(void, callback_transmit_finished, (UNUSED_ATTR void *buffer, bool all_fragments_sent))
   DURING(transmit_simple) AT_CALL(0) {
     EXPECT_TRUE(all_fragments_sent);
@@ -456,7 +467,7 @@ STUB_FUNCTION(void, command_status_callback, (UNUSED_ATTR uint8_t status, BT_HDR
 }
 
 STUB_FUNCTION(void, controller_init, (const hci_t *hci_interface))
-  DURING(start_up) AT_CALL(0) {
+  DURING(start_up_async) AT_CALL(0) {
     EXPECT_EQ(hci, hci_interface);
     return;
   }
@@ -493,8 +504,6 @@ static void reset_for(TEST_MODES_T next) {
   RESET_CALL_COUNT(hal_read_data);
   RESET_CALL_COUNT(hal_packet_finished);
   RESET_CALL_COUNT(hal_transmit_data);
-  RESET_CALL_COUNT(btsnoop_open);
-  RESET_CALL_COUNT(btsnoop_close);
   RESET_CALL_COUNT(btsnoop_capture);
   RESET_CALL_COUNT(hci_inject_open);
   RESET_CALL_COUNT(hci_inject_close);
@@ -502,6 +511,7 @@ static void reset_for(TEST_MODES_T next) {
   RESET_CALL_COUNT(low_power_cleanup);
   RESET_CALL_COUNT(low_power_wake_assert);
   RESET_CALL_COUNT(low_power_transmit_done);
+  RESET_CALL_COUNT(callback_startup_finished);
   RESET_CALL_COUNT(callback_transmit_finished);
   RESET_CALL_COUNT(command_complete_callback);
   RESET_CALL_COUNT(command_status_callback);
@@ -545,8 +555,6 @@ class HciLayerTest : public AlarmTestHarness {
       hal.read_data = hal_read_data;
       hal.packet_finished = hal_packet_finished;
       hal.transmit_data = hal_transmit_data;
-      btsnoop.open = btsnoop_open;
-      btsnoop.close = btsnoop_close;
       btsnoop.capture = btsnoop_capture;
       hci_inject.open = hci_inject_open;
       hci_inject.close = hci_inject_close;
@@ -554,6 +562,7 @@ class HciLayerTest : public AlarmTestHarness {
       low_power_manager.cleanup = low_power_cleanup;
       low_power_manager.wake_assert = low_power_wake_assert;
       low_power_manager.transmit_done = low_power_transmit_done;
+      callbacks.startup_finished = callback_startup_finished;
       callbacks.transmit_finished = callback_transmit_finished;
       controller.init = controller_init;
       controller.begin_acl_size_fetch = controller_begin_acl_size_fetch;
@@ -562,14 +571,18 @@ class HciLayerTest : public AlarmTestHarness {
 
       done = semaphore_new(0);
 
-      reset_for(start_up);
-      hci->start_up(test_addr, &callbacks);
+      reset_for(start_up_async);
+      hci->start_up_async(test_addr, &callbacks);
+      semaphore_wait(done);
 
       EXPECT_CALL_COUNT(vendor_open, 1);
       EXPECT_CALL_COUNT(hal_init, 1);
       EXPECT_CALL_COUNT(low_power_init, 1);
       EXPECT_CALL_COUNT(vendor_set_callback, 3);
       EXPECT_CALL_COUNT(controller_init, 1);
+      EXPECT_CALL_COUNT(hal_open, 1);
+      EXPECT_CALL_COUNT(vendor_send_async_command, 1);
+      EXPECT_CALL_COUNT(callback_startup_finished, 1);
     }
 
     virtual void TearDown() {
@@ -594,32 +607,6 @@ class HciLayerTest : public AlarmTestHarness {
     hci_callbacks_t callbacks;
 };
 
-static void signal_work_item(UNUSED_ATTR void *context) {
-  semaphore_post(done);
-}
-
-static void flush_thread(thread_t *thread) {
-  thread_post(thread, signal_work_item, NULL);
-  semaphore_wait(done);
-}
-
-TEST_F(HciLayerTest, test_cycle_power) {
-  reset_for(cycle_power);
-  hci->set_chip_power_on(true);
-  hci->set_chip_power_on(false);
-
-  EXPECT_CALL_COUNT(vendor_send_command, 2);
-}
-
-TEST_F(HciLayerTest, test_preload) {
-  reset_for(preload);
-  hci->do_preload();
-
-  flush_thread(internal_thread);
-  EXPECT_CALL_COUNT(hal_open, 1);
-  EXPECT_CALL_COUNT(vendor_send_async_command, 1);
-}
-
 TEST_F(HciLayerTest, test_postload) {
   reset_for(postload);
   hci->do_postload();
@@ -753,15 +740,3 @@ TEST_F(HciLayerTest, test_transmit_command_command_complete) {
 }
 
 // TODO(zachoverflow): test post-reassembly better, stub out fragmenter instead of using it
-
-TEST_F(HciLayerTest, test_turn_on_logging) {
-  reset_for(turn_on_logging);
-  hci->turn_on_logging(logging_path);
-  EXPECT_CALL_COUNT(btsnoop_open, 1);
-}
-
-TEST_F(HciLayerTest, test_turn_off_logging) {
-  reset_for(turn_off_logging);
-  hci->turn_off_logging();
-  EXPECT_CALL_COUNT(btsnoop_close, 1);
-}
index b7ef9d3..424eedd 100755 (executable)
@@ -40,6 +40,7 @@
 #include "bte.h"
 #include "btif_common.h"
 #include "btu.h"
+#include "btsnoop.h"
 #include "bt_utils.h"
 #include "fixed_queue.h"
 #include "gki.h"
 #define HCI_LOGGING_FILENAME  "/data/misc/bluedroid/btsnoop_hci.log"
 #endif
 
-/* Stack preload process maximum retry attempts  */
-#ifndef PRELOAD_MAX_RETRY_ATTEMPTS
-#define PRELOAD_MAX_RETRY_ATTEMPTS 0
-#endif
-
-/*******************************************************************************
-**  Local type definitions
-*******************************************************************************/
-/* Preload retry control block */
-typedef struct
-{
-    int     retry_counts;
-    alarm_t *alarm;
-} bt_preload_retry_cb_t;
-
 /******************************************************************************
 **  Variables
 ******************************************************************************/
@@ -118,8 +104,8 @@ static const size_t BTU_L2CAP_ALARM_HASH_MAP_SIZE = 17;
 **  Static variables
 *******************************************************************************/
 static const hci_t *hci;
+static const btsnoop_t *btsnoop;
 static const hci_callbacks_t hci_callbacks;
-static bt_preload_retry_cb_t preload_retry_cb;
 // Lock to serialize shutdown requests from upper layer.
 static pthread_mutex_t shutdown_lock;
 
@@ -131,10 +117,6 @@ static thread_t *dispatch_thread;
 /*******************************************************************************
 **  Static functions
 *******************************************************************************/
-static void bte_hci_enable(void);
-static void bte_hci_disable(void);
-static void preload_start_wait_timer(void);
-static void preload_stop_wait_timer(void);
 static void dump_upbound_data_to_btu(fixed_queue_t *queue, void *context);
 
 /*******************************************************************************
@@ -165,6 +147,8 @@ void bte_main_boot_entry(void)
     if (!hci)
       ALOGE("%s could not get hci layer interface.", __func__);
 
+    btsnoop = btsnoop_get_interface();
+
     upbound_data = fixed_queue_new(SIZE_MAX);
     dispatch_thread = thread_new("hci_dispatch");
 
@@ -177,9 +161,6 @@ void bte_main_boot_entry(void)
 
     data_dispatcher_register_default(hci->upward_dispatcher, upbound_data);
 
-    memset(&preload_retry_cb, 0, sizeof(bt_preload_retry_cb_t));
-    preload_retry_cb.alarm = alarm_new();
-
     bte_load_conf(BTE_STACK_CONF_FILE);
 #if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
     bte_load_ble_conf(BTE_BLE_STACK_CONF_FILE);
@@ -191,7 +172,7 @@ void bte_main_boot_entry(void)
 #endif
 
     pthread_mutex_init(&shutdown_lock, NULL);
-
+    btsnoop->set_logging_path(hci_logfile);
 }
 
 /******************************************************************************
@@ -205,11 +186,14 @@ void bte_main_boot_entry(void)
 ******************************************************************************/
 void bte_main_shutdown()
 {
-    alarm_free(preload_retry_cb.alarm);
-    preload_retry_cb.alarm = NULL;
+    thread_free(dispatch_thread);
+    data_dispatcher_register_default(hci_layer_get_interface()->upward_dispatcher, NULL);
+    fixed_queue_free(upbound_data, NULL);
 
-    pthread_mutex_destroy(&shutdown_lock);
+    dispatch_thread = NULL;
+    upbound_data = NULL;
 
+    pthread_mutex_destroy(&shutdown_lock);
     GKI_shutdown();
 }
 
@@ -247,7 +231,8 @@ void bte_main_enable()
 
     BTU_StartUp();
 
-    bte_hci_enable();
+    btsnoop->set_is_running(hci_logging_enabled || hci_logging_config);
+    assert(hci->start_up_async(btif_local_bd_addr.address, &hci_callbacks));
 }
 
 /******************************************************************************
@@ -264,8 +249,16 @@ void bte_main_disable(void)
 {
     APPL_TRACE_DEBUG("%s", __FUNCTION__);
 
-    preload_stop_wait_timer();
-    bte_hci_disable();
+    if (hci) {
+      // Shutdown is not thread safe and must be protected.
+      pthread_mutex_lock(&shutdown_lock);
+
+      btsnoop->set_is_running(false);
+      hci->shut_down();
+
+      pthread_mutex_unlock(&shutdown_lock);
+    }
+
     BTU_ShutDown();
 
     fixed_queue_free(btu_bta_msg_queue, NULL);
@@ -295,153 +288,8 @@ void bte_main_disable(void)
 ******************************************************************************/
 void bte_main_config_hci_logging(BOOLEAN enable, BOOLEAN bt_disabled)
 {
-    int old = (hci_logging_enabled == TRUE) || (hci_logging_config == TRUE);
-    int new;
-
-    hci_logging_config = enable;
-
-    new = (hci_logging_enabled == TRUE) || (hci_logging_config == TRUE);
-
-    if ((old == new) || bt_disabled) {
-        return;
-    }
-
-    if (new)
-      hci->turn_on_logging(hci_logfile);
-    else
-      hci->turn_off_logging();
-}
-
-/******************************************************************************
-**
-** Function         bte_hci_enable
-**
-** Description      Enable HCI & Vendor modules
-**
-** Returns          None
-**
-******************************************************************************/
-static void bte_hci_enable(void)
-{
-    APPL_TRACE_DEBUG("%s", __FUNCTION__);
-
-    preload_start_wait_timer();
-
-    bool success = hci->start_up(btif_local_bd_addr.address, &hci_callbacks);
-    APPL_TRACE_EVENT("libbt-hci start_up returns %d", success);
-
-    assert(success);
-
-    if (hci_logging_enabled == TRUE || hci_logging_config == TRUE)
-        hci->turn_on_logging(hci_logfile);
-
-#if (defined (BT_CLEAN_TURN_ON_DISABLED) && BT_CLEAN_TURN_ON_DISABLED == TRUE)
-    APPL_TRACE_DEBUG("%s not turning off the chip before turning it on", __FUNCTION__);
-
-    /* Do not power off the chip before powering on  if BT_CLEAN_TURN_ON_DISABLED flag
-     is defined and set to TRUE to avoid below mentioned issue.
-
-     Wingray kernel driver maintains a combined  counter to keep track of
-     BT-Wifi state. Invoking  set_power(BT_HC_CHIP_PWR_OFF) when the BT is already
-     in OFF state causes this counter to be incorrectly decremented and results in undesired
-     behavior of the chip.
-
-     This is only a workaround and when the issue is fixed in the kernel this work around
-     should be removed. */
-#else
-    /* toggle chip power to ensure we will reset chip in case
-       a previous stack shutdown wasn't completed gracefully */
-    hci->set_chip_power_on(false);
-#endif
-    hci->set_chip_power_on(true);
-    hci->do_preload();
-}
-
-/******************************************************************************
-**
-** Function         bte_hci_disable
-**
-** Description      Disable HCI & Vendor modules
-**
-** Returns          None
-**
-******************************************************************************/
-static void bte_hci_disable(void)
-{
-    APPL_TRACE_DEBUG("%s", __FUNCTION__);
-
-    if (!hci)
-        return;
-
-    // Shutdown is not thread safe and must be protected.
-    pthread_mutex_lock(&shutdown_lock);
-
-    if (hci_logging_enabled == TRUE ||  hci_logging_config == TRUE)
-        hci->turn_off_logging();
-    hci->shut_down();
-
-    pthread_mutex_unlock(&shutdown_lock);
-}
-
-/*******************************************************************************
-**
-** Function        preload_wait_timeout
-**
-** Description     Timeout thread of preload watchdog timer
-**
-** Returns         None
-**
-*******************************************************************************/
-static void preload_wait_timeout(UNUSED_ATTR void *context)
-{
-    APPL_TRACE_ERROR("...preload_wait_timeout (retried:%d/max-retry:%d)...",
-                        preload_retry_cb.retry_counts,
-                        PRELOAD_MAX_RETRY_ATTEMPTS);
-
-    if (preload_retry_cb.retry_counts++ < PRELOAD_MAX_RETRY_ATTEMPTS)
-    {
-        bte_hci_disable();
-        GKI_delay(100);
-        bte_hci_enable();
-    }
-    else
-    {
-        // Inform the bt jni thread initialization has failed.
-        btif_transfer_context(btif_init_fail, 0, NULL, 0, NULL);
-    }
-}
-
-/*******************************************************************************
-**
-** Function        preload_start_wait_timer
-**
-** Description     Launch startup watchdog timer
-**
-** Returns         None
-**
-*******************************************************************************/
-static void preload_start_wait_timer(void)
-{
-    uint32_t timeout_ms;
-    char timeout_prop[PROPERTY_VALUE_MAX];
-    if (!property_get("bluetooth.enable_timeout_ms", timeout_prop, "3000") || (timeout_ms = atoi(timeout_prop)) < 100)
-        timeout_ms = 3000;
-
-    alarm_set(preload_retry_cb.alarm, timeout_ms, preload_wait_timeout, NULL);
-}
-
-/*******************************************************************************
-**
-** Function        preload_stop_wait_timer
-**
-** Description     Stop preload watchdog timer
-**
-** Returns         None
-**
-*******************************************************************************/
-static void preload_stop_wait_timer(void)
-{
-    alarm_cancel(preload_retry_cb.alarm);
+  hci_logging_config = enable;
+  btsnoop->set_is_running((hci_logging_config || hci_logging_enabled) && !bt_disabled);
 }
 
 /******************************************************************************
@@ -598,7 +446,7 @@ void bte_main_hci_send (BT_HDR *p_msg, UINT16 event)
 
 /******************************************************************************
 **
-** Function         preload_cb
+** Function         hci_startup_cb
 **
 ** Description      HOST/CONTROLLER LIB CALLBACK API - This function is called
 **                  when the libbt-hci completed stack preload process
@@ -606,16 +454,16 @@ void bte_main_hci_send (BT_HDR *p_msg, UINT16 event)
 ** Returns          None
 **
 ******************************************************************************/
-static void preload_cb(bool success)
+static void hci_startup_cb(bool success)
 {
     APPL_TRACE_EVENT("HC preload_cb %d [1:SUCCESS 0:FAIL]", success);
 
-    if (success)
-    {
-        preload_stop_wait_timer();
-
+    if (success) {
         /* notify BTU task that libbt-hci is ready */
         GKI_send_event(BTU_TASK, BT_EVT_PRELOAD_CMPL);
+    } else {
+        /* Notify BTIF_TASK that the init procedure had failed*/
+        GKI_send_event(BTIF_TASK, BT_EVT_HARDWARE_INIT_FAIL);
     }
 }
 
@@ -664,6 +512,6 @@ static void tx_result(void *p_buf, bool all_fragments_sent)
 **   The libbt-hci Callback Functions Table
 *****************************************************************************/
 static const hci_callbacks_t hci_callbacks = {
-    preload_cb,
+    hci_startup_cb,
     tx_result
 };