OSDN Git Service

Avoid NULL pointer usage of startup_future in case of HCI startup timeout
authorPavlin Radoslavov <pavlin@google.com>
Wed, 4 May 2016 03:20:06 +0000 (20:20 -0700)
committerPavlin Radoslavov <pavlin@google.com>
Wed, 4 May 2016 23:40:09 +0000 (16:40 -0700)
Previously, the startup_timer was created within the HCI layer start_up()
function, and after several vendor calls, we created the startup_future
that is used elsewhere. However, if any of the vendor calls blocks for
very long time, the startup_timer will timeout.
The startup_timer_expired() callback will try to use startup_future
that is still NULL, and that will trigger an assert.

The issue is avoided by creating the startup_future right before
the startup_timer is scheduled.

Bug: 28528815
Change-Id: Ib9f2c6581a86d3df0fd4d02d0b4c290663b5cfa1

hci/src/hci_layer.c

index 9a9c5e6..a30f8c4 100644 (file)
@@ -193,9 +193,6 @@ static future_t *start_up(void) {
     goto error;
   }
 
-  // Make sure we run in a bounded amount of time
-  alarm_set(startup_timer, startup_timeout_ms, startup_timer_expired, NULL);
-
   epilog_timer = alarm_new("hci.epilog_timer");
   if (!epilog_timer) {
     LOG_ERROR(LOG_TAG, "%s unable to create epilog timer.", __func__);
@@ -234,6 +231,11 @@ static future_t *start_up(void) {
 
   memset(incoming_packets, 0, sizeof(incoming_packets));
 
+  // Make sure we run in a bounded amount of time
+  future_t *local_startup_future = future_new();
+  startup_future = local_startup_future;
+  alarm_set(startup_timer, startup_timeout_ms, startup_timer_expired, NULL);
+
   packet_fragmenter->init(&packet_fragmenter_callbacks);
 
   fixed_queue_register_dequeue(command_queue, thread_get_reactor(thread), event_command_ready, NULL);
@@ -267,8 +269,6 @@ static future_t *start_up(void) {
   power_state = BT_VND_PWR_ON;
   vendor->send_command(VENDOR_CHIP_POWER_CONTROL, &power_state);
 
-  future_t *local_startup_future = future_new();
-  startup_future = local_startup_future;
   LOG_DEBUG(LOG_TAG, "%s starting async portion", __func__);
   thread_post(thread, event_finish_startup, NULL);
   return local_startup_future;