Add non-repeating timer wrapper for alarm

Refactor the hci layer to use it.

The timer wrapper allows you to specify the duration, etc at construction time
rather than at start time, making some usage patterns of alarm more convenient.
diff --git a/system/hci/src/hci_layer.c b/system/hci/src/hci_layer.c
index c98c7c3..171d18b 100644
--- a/system/hci/src/hci_layer.c
+++ b/system/hci/src/hci_layer.c
@@ -21,7 +21,6 @@
 #include <assert.h>
 #include <utils/Log.h>
 
-#include "alarm.h"
 #include "buffer_allocator.h"
 #include "btsnoop.h"
 #include "controller.h"
@@ -33,6 +32,7 @@
 #include "hci_layer.h"
 #include "list.h"
 #include "low_power_manager.h"
+#include "non_repeating_timer.h"
 #include "osi.h"
 #include "packet_fragmenter.h"
 #include "reactor.h"
@@ -111,7 +111,7 @@
 
 static volatile bool firmware_is_configured = false;
 static volatile bool has_shut_down = false;
-static alarm_t *epilog_alarm;
+static non_repeating_timer_t *epilog_timer;
 
 // Outbound-related
 static int command_credits = 1;
@@ -119,7 +119,7 @@
 static fixed_queue_t *packet_queue;
 
 // Inbound-related
-static alarm_t *command_response_alarm;
+static non_repeating_timer_t *command_response_timer;
 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];
@@ -134,6 +134,7 @@
 static void sco_config_callback(bool success);
 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);
 
@@ -154,15 +155,15 @@
 
   pthread_mutex_init(&commands_pending_response_lock, NULL);
 
-  epilog_alarm = alarm_new();
-  if (!epilog_alarm) {
-    ALOGE("%s unable to create epilog alarm.", __func__);
+  epilog_timer = non_repeating_timer_new(EPILOG_TIMEOUT_MS, epilog_wait_timer_expired, NULL);
+  if (!epilog_timer) {
+    ALOGE("%s unable to create epilog timer.", __func__);
     goto error;
   }
 
-  command_response_alarm = alarm_new();
-  if (!command_response_alarm) {
-    ALOGE("%s unable to create command response alarm.", __func__);
+  command_response_timer = non_repeating_timer_new(COMMAND_PENDING_TIMEOUT, command_timed_out, NULL);
+  if (!command_response_timer) {
+    ALOGE("%s unable to create command response timer.", __func__);
     goto error;
   }
 
@@ -229,7 +230,7 @@
 
   if (thread) {
     if (firmware_is_configured) {
-      alarm_set(epilog_alarm, EPILOG_TIMEOUT_MS, epilog_wait_timer_expired, NULL);
+      non_repeating_timer_restart(epilog_timer);
       thread_post(thread, event_epilog, NULL);
     } else {
       thread_stop(thread);
@@ -246,9 +247,8 @@
 
   packet_fragmenter->cleanup();
 
-
-  alarm_free(epilog_alarm);
-  alarm_free(command_response_alarm);
+  non_repeating_timer_free(epilog_timer);
+  non_repeating_timer_free(command_response_timer);
 
   low_power_manager->cleanup();
   hal->close();
@@ -349,13 +349,6 @@
   kill(getpid(), SIGKILL);
 }
 
-static void restart_command_timeout_alarm() {
-  if (list_is_empty(commands_pending_response))
-    alarm_cancel(command_response_alarm);
-  else
-    alarm_set(command_response_alarm, COMMAND_PENDING_TIMEOUT, command_timed_out, NULL);
-}
-
 static waiting_command_t *get_waiting_command(command_opcode_t opcode) {
   pthread_mutex_lock(&commands_pending_response_lock);
 
@@ -419,7 +412,8 @@
 
   return false;
 intercepted:;
-  restart_command_timeout_alarm();
+  non_repeating_timer_restart_if(command_response_timer, !list_is_empty(commands_pending_response));
+
   if (wait_entry) {
     // If it has a callback, it's responsible for freeing the packet
     if (event_code == HCI_COMMAND_STATUS_EVT || !wait_entry->complete_callback)
@@ -494,7 +488,7 @@
     packet_fragmenter->fragment_and_dispatch(wait_entry->command);
     low_power_manager->transmit_done();
 
-    restart_command_timeout_alarm();
+    non_repeating_timer_restart_if(command_response_timer, !list_is_empty(commands_pending_response));
   }
 }
 
diff --git a/system/osi/Android.mk b/system/osi/Android.mk
index ab7b4b4..f3313f2 100644
--- a/system/osi/Android.mk
+++ b/system/osi/Android.mk
@@ -34,6 +34,7 @@
     ./src/hash_functions.c \
     ./src/hash_map.c \
     ./src/list.c \
+    ./src/non_repeating_timer.c \
     ./src/reactor.c \
     ./src/semaphore.c \
     ./src/socket.c \
diff --git a/system/osi/include/non_repeating_timer.h b/system/osi/include/non_repeating_timer.h
new file mode 100644
index 0000000..de8aabf
--- /dev/null
+++ b/system/osi/include/non_repeating_timer.h
@@ -0,0 +1,48 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Google, Inc.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#pragma once
+
+#include <stdbool.h>
+
+#include "alarm.h"
+
+typedef struct non_repeating_timer_t non_repeating_timer_t;
+
+// Creates a new non repeating timer of |duration| with callback |cb|. |cb| will be
+// called back in the context of an upspecified thread, and may not be NULL. |data|
+// is a context variable for the callback and may be NULL. The returned object must
+// be freed by calling |non_repeating_timer_free|. Returns NULL on failure.
+non_repeating_timer_t *non_repeating_timer_new(period_ms_t duration, alarm_callback_t cb, void *data);
+
+// Frees a non repeating timer created by |non_repeating_timer_new|. |timer| may be
+// NULL. If the timer is currently running, it will be cancelled. It is not safe to
+// call |non_repeating_timer_free| from inside the callback of a non repeating timer.
+void non_repeating_timer_free(non_repeating_timer_t *timer);
+
+// Restarts the non repeating timer. If it is currently running, the timer is reset.
+// |timer| may not be NULL.
+void non_repeating_timer_restart(non_repeating_timer_t *timer);
+
+// Restarts the non repeating timer if |condition| is true, otherwise ensures it is
+// not running. |timer| may not be NULL.
+void non_repeating_timer_restart_if(non_repeating_timer_t *timer, bool condition);
+
+// Cancels the non repeating timer if it is currently running. All the semantics of
+// |alarm_cancel| apply here. |timer| may not be NULL.
+void non_repeating_timer_cancel(non_repeating_timer_t *timer);
diff --git a/system/osi/src/non_repeating_timer.c b/system/osi/src/non_repeating_timer.c
new file mode 100644
index 0000000..0c32e3d
--- /dev/null
+++ b/system/osi/src/non_repeating_timer.c
@@ -0,0 +1,74 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Google, Inc.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#include <assert.h>
+
+#include "allocator.h"
+#include "osi.h"
+#include "non_repeating_timer.h"
+
+struct non_repeating_timer_t {
+  alarm_t *alarm;
+  period_ms_t duration;
+  alarm_callback_t callback;
+  void *data;
+};
+
+non_repeating_timer_t *non_repeating_timer_new(period_ms_t duration, alarm_callback_t cb, void *data) {
+  assert(cb != NULL);
+
+  non_repeating_timer_t *ret = osi_calloc(sizeof(non_repeating_timer_t));
+
+  ret->alarm = alarm_new();
+  if (!ret->alarm)
+    goto error;
+
+  ret->duration = duration;
+  ret->callback = cb;
+  ret->data = data;
+
+  return ret;
+error:;
+  non_repeating_timer_free(ret);
+  return NULL;
+}
+
+void non_repeating_timer_free(non_repeating_timer_t *timer) {
+  if (!timer)
+    return;
+
+  alarm_free(timer->alarm);
+  osi_free(timer);
+}
+
+void non_repeating_timer_restart(non_repeating_timer_t *timer) {
+  non_repeating_timer_restart_if(timer, true);
+}
+
+void non_repeating_timer_restart_if(non_repeating_timer_t *timer, bool condition) {
+  assert(timer != NULL);
+  if (condition)
+    alarm_set(timer->alarm, timer->duration, timer->callback, timer->data);
+  else
+    non_repeating_timer_cancel(timer);
+}
+
+void non_repeating_timer_cancel(non_repeating_timer_t *timer) {
+  assert(timer != NULL);
+  alarm_cancel(timer->alarm);
+}