OSDN Git Service

Clean up messy dispatch in bt_hci_bdroid by using new primitives.
authorSharvil Nanavati <sharvil@google.com>
Sun, 6 Jul 2014 04:21:38 +0000 (21:21 -0700)
committerSharvil Nanavati <sharvil@google.com>
Wed, 16 Jul 2014 21:02:12 +0000 (14:02 -0700)
Instead of dispatching onto a worker thread by setting bits of a
bitfield and then having the thread pull data from shared data
structures, this code uses the previously defined primitives to
write to a synchronized thread event queue. It's advantageous because
it's more direct dispatch (you specify which function you want to
call on the worker thread instead of mapping bitfields to a function),
it avoids a lot of boilerplate code, function calls have predictable
ordering, and it uses generic infrastructure instead of building a
custom dispatch + synchronized data strucures.

Change-Id: If938e4fd47c8ddf328a29d104151f900ec659588

hci/include/bt_hci_bdroid.h
hci/include/btsnoop.h
hci/src/bt_hci_bdroid.c
hci/src/hci_h4.c
hci/src/hci_mct.c
hci/src/lpm.c
hci/src/userial.c
hci/src/userial_mct.c
hci/src/vendor.c

index bb285d9..85b2870 100644 (file)
@@ -27,8 +27,7 @@
  *
  ******************************************************************************/
 
-#ifndef BT_HCI_BDROID_H
-#define BT_HCI_BDROID_H
+#pragma once
 
 #include "bt_hci_lib.h"
 
 ******************************************************************************/
 
 #ifndef FALSE
-#define FALSE  0
+#define FALSE  false
 #endif
 
 #ifndef TRUE
-#define TRUE   (!FALSE)
+#define TRUE   true
 #endif
 
-#ifndef BTHC_LINUX_BASE_POLICY
-#define BTHC_LINUX_BASE_POLICY SCHED_NORMAL
-#endif
-
-#if (BTHC_LINUX_BASE_POLICY != SCHED_NORMAL)
-#ifndef BTHC_LINUX_BASE_PRIORITY
-#define BTHC_LINUX_BASE_PRIORITY 30
-#endif
-
-#ifndef BTHC_USERIAL_READ_THREAD_PRIORITY
-#define BTHC_USERIAL_READ_THREAD_PRIORITY (BTHC_LINUX_BASE_PRIORITY)
-#endif
-
-#ifndef BTHC_MAIN_THREAD_PRIORITY
-#define BTHC_MAIN_THREAD_PRIORITY (BTHC_LINUX_BASE_PRIORITY-1)
-#endif
-#endif  // (BTHC_LINUX_BASE_POLICY != SCHED_NORMAL)
-
 #define HCI_ACL_MAX_SIZE 1024
 #define HCI_MAX_FRAME_SIZE (HCI_ACL_MAX_SIZE + 4)
 
 /* Host/Controller lib internal event ID */
-#define HC_EVENT_PRELOAD               0x0001
-#define HC_EVENT_POSTLOAD              0x0002
-#define HC_EVENT_RX                    0x0004
-#define HC_EVENT_TX                    0x0008
-#define HC_EVENT_LPM_ENABLE            0x0010
-#define HC_EVENT_LPM_DISABLE           0x0020
-#define HC_EVENT_LPM_WAKE_DEVICE       0x0040
-#define HC_EVENT_LPM_ALLOW_SLEEP       0x0080
-#define HC_EVENT_LPM_IDLE_TIMEOUT      0x0100
-#define HC_EVENT_EXIT                  0x0200
-#define HC_EVENT_EPILOG                0x0400
-#define HC_EVENT_TX_CMD                0x0800
+typedef enum {
+  HC_EVENT_LPM_IDLE_TIMEOUT,
+} bthc_event_t;
 
 #define MSG_CTRL_TO_HC_CMD             0x0100 /* evt mask used by HC_EVENT_TX_CMD */
 
@@ -126,7 +98,6 @@ typedef struct
 
 #define BT_HC_HDR_SIZE (sizeof(HC_BT_HDR))
 
-
 typedef struct _hc_buffer_hdr
 {
     struct _hc_buffer_hdr *p_next;   /* next buffer in the queue */
@@ -148,15 +119,8 @@ extern bt_hc_callbacks_t *bt_hc_cbacks;
 **  Functions
 ******************************************************************************/
 
-/*******************************************************************************
-**
-** Function        bthc_signal_event
-**
-** Description     Perform context switch to bt_hc main thread
-**
-** Returns         None
-**
-*******************************************************************************/
-extern void bthc_signal_event(uint16_t event);
-
-#endif /* BT_HCI_BDROID_H */
+// Called when a buffer has been produced by the serial layer and should be
+// processed by the HCI layer.
+void bthc_rx_ready(void);
+void bthc_tx(HC_BT_HDR *buf);
+void bthc_idle_timeout(void);
index 4f2d23b..5dedf68 100644 (file)
@@ -2,6 +2,8 @@
 
 #include <stdbool.h>
 
+#include "bt_hci_bdroid.h"
+
 void btsnoop_open(const char *p_path);
 void btsnoop_close(void);
 
index 93266af..174cc1f 100644 (file)
 
 #include <assert.h>
 #include <utils/Log.h>
-#include <pthread.h>
+
+#include "btsnoop.h"
 #include "bt_hci_bdroid.h"
+#include "bt_utils.h"
 #include "bt_vendor_lib.h"
-#include "utils.h"
 #include "hci.h"
+#include "osi.h"
+#include "thread.h"
 #include "userial.h"
+#include "utils.h"
 #include "vendor.h"
-#include "bt_utils.h"
-#include "btsnoop.h"
-#include <sys/prctl.h>
 
 #ifndef BTHC_DBG
 #define BTHC_DBG FALSE
@@ -51,9 +52,7 @@
 #endif
 
 /* Vendor epilog process timeout period  */
-#ifndef EPILOG_TIMEOUT_MS
-#define EPILOG_TIMEOUT_MS 3000  // 3 seconds
-#endif
+static const uint32_t EPILOG_TIMEOUT_MS = 3000;
 
 /******************************************************************************
 **  Externs
@@ -73,9 +72,8 @@ void init_vnd_if(unsigned char *local_bdaddr);
 ******************************************************************************/
 
 bt_hc_callbacks_t *bt_hc_cbacks = NULL;
-BUFFER_Q tx_q;
 tHCI_IF *p_hci_if;
-volatile uint8_t fwcfg_acked;
+volatile bool fwcfg_acked;
 
 /******************************************************************************
 **  Local type definitions
@@ -84,11 +82,8 @@ volatile uint8_t fwcfg_acked;
 /* Host/Controller lib thread control block */
 typedef struct
 {
-    pthread_t       worker_thread;
-    pthread_mutex_t mutex;
-    pthread_cond_t  cond;
-    BUFFER_Q        cmd_q;
-    uint8_t         epilog_timer_created;
+    thread_t        *worker_thread;
+    bool            epilog_timer_created;
     timer_t         epilog_timer_id;
 } bt_hc_cb_t;
 
@@ -97,22 +92,138 @@ typedef struct
 ******************************************************************************/
 
 static bt_hc_cb_t hc_cb;
-static volatile uint8_t lib_running = 0;
-static volatile uint16_t ready_events = 0;
-static volatile uint8_t tx_cmd_pkts_pending = FALSE;
+static bool tx_cmd_pkts_pending = false;
+static BUFFER_Q tx_q;
 
 /******************************************************************************
 **  Functions
 ******************************************************************************/
 
-static void *bt_hc_worker_thread(void *arg);
+static void event_preload(UNUSED_ATTR void *context) {
+  userial_open(USERIAL_PORT_1);
+  vendor_send_command(BT_VND_OP_FW_CFG, NULL);
+}
+
+static void event_postload(UNUSED_ATTR void *context) {
+  /* Start from SCO related H/W configuration, if SCO configuration
+   * is required. Then, follow with reading requests of getting
+   * ACL data length for both BR/EDR and LE.
+   */
+  int result = vendor_send_command(BT_VND_OP_SCO_CFG, NULL);
+  if (result == -1)
+    p_hci_if->get_acl_max_len();
+}
 
-void bthc_signal_event(uint16_t event)
-{
-    pthread_mutex_lock(&hc_cb.mutex);
-    ready_events |= event;
-    pthread_cond_signal(&hc_cb.cond);
-    pthread_mutex_unlock(&hc_cb.mutex);
+static void event_tx(UNUSED_ATTR void *context) {
+  /*
+   *  We will go through every packets in the tx queue.
+   *  Fine to clear tx_cmd_pkts_pending.
+   */
+  tx_cmd_pkts_pending = false;
+  HC_BT_HDR *sending_msg_que[64];
+  size_t sending_msg_count = 0;
+  int sending_hci_cmd_pkts_count = 0;
+  utils_lock();
+  HC_BT_HDR *p_next_msg = tx_q.p_first;
+  while (p_next_msg && sending_msg_count < ARRAY_SIZE(sending_msg_que))
+  {
+    if ((p_next_msg->event & MSG_EVT_MASK)==MSG_STACK_TO_HC_HCI_CMD)
+    {
+      /*
+       *  if we have used up controller's outstanding HCI command
+       *  credits (normally is 1), skip all HCI command packets in
+       *  the queue.
+       *  The pending command packets will be sent once controller
+       *  gives back us credits through CommandCompleteEvent or
+       *  CommandStatusEvent.
+       */
+      if (tx_cmd_pkts_pending ||
+          (sending_hci_cmd_pkts_count >= num_hci_cmd_pkts))
+      {
+        tx_cmd_pkts_pending = true;
+        p_next_msg = utils_getnext(p_next_msg);
+        continue;
+      }
+      sending_hci_cmd_pkts_count++;
+    }
+
+    HC_BT_HDR *p_msg = p_next_msg;
+    p_next_msg = utils_getnext(p_msg);
+    utils_remove_from_queue_unlocked(&tx_q, p_msg);
+    sending_msg_que[sending_msg_count++] = p_msg;
+  }
+  utils_unlock();
+  for(size_t i = 0; i < sending_msg_count; i++)
+    p_hci_if->send(sending_msg_que[i]);
+  if (tx_cmd_pkts_pending)
+    BTHCDBG("Used up Tx Cmd credits");
+}
+
+static void event_rx(UNUSED_ATTR void *context) {
+#ifndef HCI_USE_MCT
+  p_hci_if->rcv();
+
+  if (tx_cmd_pkts_pending && num_hci_cmd_pkts > 0) {
+    // Got HCI Cmd credits from controller. Send whatever data
+    // we have in our tx queue. We can call |event_tx| directly
+    // here since we're already on the worker thread.
+    event_tx(NULL);
+  }
+#endif
+}
+
+static void event_lpm_enable(UNUSED_ATTR void *context) {
+  lpm_enable(true);
+}
+
+static void event_lpm_disable(UNUSED_ATTR void *context) {
+  lpm_enable(false);
+}
+
+static void event_lpm_wake_device(UNUSED_ATTR void *context) {
+  lpm_wake_assert();
+}
+
+static void event_lpm_allow_sleep(UNUSED_ATTR void *context) {
+  lpm_allow_bt_device_sleep();
+}
+
+static void event_lpm_idle_timeout(UNUSED_ATTR void *context) {
+  lpm_wake_deassert();
+}
+
+static void event_epilog(UNUSED_ATTR void *context) {
+  vendor_send_command(BT_VND_OP_EPILOG, NULL);
+}
+
+static void event_tx_cmd(void *msg) {
+  HC_BT_HDR *p_msg = (HC_BT_HDR *)msg;
+
+  BTHCDBG("%s: p_msg: %p, event: 0x%x", __func__, p_msg, p_msg->event);
+
+  int event = p_msg->event & MSG_EVT_MASK;
+  int sub_event = p_msg->event & MSG_SUB_EVT_MASK;
+  if (event == MSG_CTRL_TO_HC_CMD && sub_event == BT_HC_AUDIO_STATE) {
+    vendor_send_command(BT_VND_OP_SET_AUDIO_STATE, p_msg->data);
+  } else {
+    ALOGW("%s (event: 0x%x, sub_event: 0x%x) not supported", __func__, event, sub_event);
+  }
+
+  bt_hc_cbacks->dealloc(msg);
+}
+
+void bthc_rx_ready(void) {
+  thread_post(hc_cb.worker_thread, event_rx, NULL);
+}
+
+void bthc_tx(HC_BT_HDR *buf) {
+  if (buf)
+    utils_enqueue(&tx_q, buf);
+  thread_post(hc_cb.worker_thread, event_tx, NULL);
+}
+
+void bthc_idle_timeout(void) {
+  thread_post(hc_cb.worker_thread, event_lpm_idle_timeout, NULL);
 }
 
 /*******************************************************************************
@@ -124,11 +235,11 @@ void bthc_signal_event(uint16_t event)
 ** Returns         None
 **
 *******************************************************************************/
-static void epilog_wait_timeout(union sigval arg)
+static void epilog_wait_timeout(UNUSED_ATTR union sigval arg)
 {
-    UNUSED(arg);
     ALOGI("...epilog_wait_timeout...");
-    bthc_signal_event(HC_EVENT_EXIT);
+    thread_free(hc_cb.worker_thread);
+    hc_cb.worker_thread = NULL;
 }
 
 /*******************************************************************************
@@ -156,7 +267,7 @@ static void epilog_wait_timer(void)
 
     if (status == 0)
     {
-        hc_cb.epilog_timer_created = 1;
+        hc_cb.epilog_timer_created = true;
         ts.it_value.tv_sec = timeout_ms/1000;
         ts.it_value.tv_nsec = 1000000*(timeout_ms%1000);
         ts.it_interval.tv_sec = 0;
@@ -169,7 +280,7 @@ static void epilog_wait_timer(void)
     else
     {
         ALOGE("Failed to create epilog watchdog timer");
-        hc_cb.epilog_timer_created = 0;
+        hc_cb.epilog_timer_created = false;
     }
 }
 
@@ -181,9 +292,7 @@ static void epilog_wait_timer(void)
 
 static int init(const bt_hc_callbacks_t* p_cb, unsigned char *local_bdaddr)
 {
-    pthread_attr_t thread_attr;
-    struct sched_param param;
-    int policy, result;
+    int result;
 
     ALOGI("init");
 
@@ -193,8 +302,8 @@ static int init(const bt_hc_callbacks_t* p_cb, unsigned char *local_bdaddr)
         return BT_HC_STATUS_FAIL;
     }
 
-    hc_cb.epilog_timer_created = 0;
-    fwcfg_acked = FALSE;
+    hc_cb.epilog_timer_created = false;
+    fwcfg_acked = false;
 
     /* store reference to user callbacks */
     bt_hc_cbacks = (bt_hc_callbacks_t *) p_cb;
@@ -217,41 +326,18 @@ static int init(const bt_hc_callbacks_t* p_cb, unsigned char *local_bdaddr)
 
     utils_queue_init(&tx_q);
 
-    if (lib_running)
+    if (hc_cb.worker_thread)
     {
         ALOGW("init has been called repeatedly without calling cleanup ?");
     }
 
-    lib_running = 1;
-    ready_events = 0;
-    utils_queue_init(&hc_cb.cmd_q);
-    pthread_mutex_init(&hc_cb.mutex, NULL);
-    pthread_cond_init(&hc_cb.cond, NULL);
-    pthread_attr_init(&thread_attr);
-
-    if (pthread_create(&hc_cb.worker_thread, &thread_attr, \
-                       bt_hc_worker_thread, NULL) != 0)
-    {
-        ALOGE("pthread_create failed!");
-        lib_running = 0;
+    hc_cb.worker_thread = thread_new("bt_hc_worker");
+    if (!hc_cb.worker_thread) {
+        ALOGE("%s unable to create worker thread.", __func__);
         return BT_HC_STATUS_FAIL;
     }
 
-    if(pthread_getschedparam(hc_cb.worker_thread, &policy, &param)==0)
-    {
-        policy = BTHC_LINUX_BASE_POLICY;
-#if (BTHC_LINUX_BASE_POLICY != SCHED_NORMAL)
-        param.sched_priority = BTHC_MAIN_THREAD_PRIORITY;
-#else
-        param.sched_priority = 0;
-#endif
-        result = pthread_setschedparam(hc_cb.worker_thread, policy, &param);
-        if (result != 0)
-        {
-            ALOGW("libbt-hci init: pthread_setschedparam failed (%s)", \
-                  strerror(result));
-        }
-    }
+    // TODO(sharvil): increase thread priority (raise_priority_a2dp)
 
     return BT_HC_STATUS_SUCCESS;
 }
@@ -274,122 +360,67 @@ static void set_power(bt_hc_chip_power_state_t state)
 /** Configure low power mode wake state */
 static int lpm(bt_hc_low_power_event_t event)
 {
-    uint8_t status = TRUE;
-
     switch (event)
     {
         case BT_HC_LPM_DISABLE:
-            bthc_signal_event(HC_EVENT_LPM_DISABLE);
+            thread_post(hc_cb.worker_thread, event_lpm_disable, NULL);
             break;
 
         case BT_HC_LPM_ENABLE:
-            bthc_signal_event(HC_EVENT_LPM_ENABLE);
+            thread_post(hc_cb.worker_thread, event_lpm_enable, NULL);
             break;
 
         case BT_HC_LPM_WAKE_ASSERT:
-            bthc_signal_event(HC_EVENT_LPM_WAKE_DEVICE);
+            thread_post(hc_cb.worker_thread, event_lpm_wake_device, NULL);
             break;
 
         case BT_HC_LPM_WAKE_DEASSERT:
-            bthc_signal_event(HC_EVENT_LPM_ALLOW_SLEEP);
+            thread_post(hc_cb.worker_thread, event_lpm_allow_sleep, NULL);
             break;
     }
-
-    return(status == TRUE) ? BT_HC_STATUS_SUCCESS : BT_HC_STATUS_FAIL;
+    return BT_HC_STATUS_SUCCESS;
 }
 
 
 /** Called prior to stack initialization */
-static void preload(TRANSAC transac)
-{
-    UNUSED(transac);
-    BTHCDBG("preload");
-    bthc_signal_event(HC_EVENT_PRELOAD);
+static void preload(UNUSED_ATTR TRANSAC transac) {
+  BTHCDBG("preload");
+  thread_post(hc_cb.worker_thread, event_preload, NULL);
 }
 
-
 /** Called post stack initialization */
-static void postload(TRANSAC transac)
-{
-    UNUSED(transac);
-    BTHCDBG("postload");
-    bthc_signal_event(HC_EVENT_POSTLOAD);
+static void postload(UNUSED_ATTR TRANSAC transac) {
+  BTHCDBG("postload");
+  thread_post(hc_cb.worker_thread, event_postload, NULL);
 }
 
-
 /** Transmit frame */
-static int transmit_buf(TRANSAC transac, char * p_buf, int len)
-{
-    UNUSED(p_buf);
-    UNUSED(len);
-    utils_enqueue(&tx_q, (void *) transac);
-
-    bthc_signal_event(HC_EVENT_TX);
-
-    return BT_HC_STATUS_SUCCESS;
+static int transmit_buf(TRANSAC transac, UNUSED_ATTR char *p_buf, UNUSED_ATTR int len) {
+  bthc_tx((HC_BT_HDR *)transac);
+  return BT_HC_STATUS_SUCCESS;
 }
 
-
 /** Controls HCI logging on/off */
-static int logging(bt_hc_logging_state_t state, char *p_path)
-{
-    BTHCDBG("logging %d", state);
+static int logging(bt_hc_logging_state_t state, char *p_path) {
+  BTHCDBG("logging %d", state);
 
-    if (state == BT_HC_LOGGING_ON)
-    {
-        if (p_path != NULL)
-            btsnoop_open(p_path);
-    }
-    else
-    {
-        btsnoop_close();
-    }
+  if (state != BT_HC_LOGGING_ON)
+    btsnoop_close();
+  else if (p_path != NULL)
+    btsnoop_open(p_path);
 
-    return BT_HC_STATUS_SUCCESS;
+  return BT_HC_STATUS_SUCCESS;
 }
 
 /** sends command HC controller to configure platform specific behaviour */
-static int tx_hc_cmd(TRANSAC transac, char *p_buf, int len)
-{
-    BTHCDBG("tx_hc_cmd: transac %p", transac);
-    if ((TRANSAC)0 != transac)
-   {
-        utils_enqueue(&hc_cb.cmd_q, (void *)transac);
-        bthc_signal_event(HC_EVENT_TX_CMD);
-        return BT_HC_STATUS_SUCCESS;
-    }
-    return BT_HC_STATUS_FAIL;
-}
+static int tx_hc_cmd(TRANSAC transac, char *p_buf, int len) {
+  BTHCDBG("tx_hc_cmd: transac %p", transac);
 
-/** handle HC controller command to configure platform specific behaviour */
-static int tx_hc_msg(HC_BT_HDR *p_msg)
-{
-    int ret_val = 0;
-    int event, sub_event;
-    BTHCDBG("tx_hc_msg: p_msg %p, event: 0x%x", (void *)p_msg, p_msg->event);
+  if (!transac)
+    return BT_HC_STATUS_FAIL;
 
-    event = p_msg->event & MSG_EVT_MASK;
-    sub_event = p_msg->event & MSG_SUB_EVT_MASK;
-    switch (event)
-    {
-    case MSG_CTRL_TO_HC_CMD:
-        {
-            switch (sub_event)
-            {
-            case BT_HC_AUDIO_STATE:
-                vendor_send_command(BT_VND_OP_SET_AUDIO_STATE, (p_msg+1));
-                break;
-            default:
-                ALOGW("tx_hc_msg(sub_event: 0x%x) not supported", sub_event);
-                break;
-            }
-        }
-         break;
-      default:
-        ALOGW("tx_hc_msg(event: 0x%x) not supported", event);
-        break;
-   }
-    return ret_val;
+  thread_post(hc_cb.worker_thread, event_tx_cmd, transac);
+  return BT_HC_STATUS_SUCCESS;
 }
 
 /** Closes the interface */
@@ -397,29 +428,24 @@ static void cleanup( void )
 {
     BTHCDBG("cleanup");
 
-    if (lib_running)
+    if (hc_cb.worker_thread)
     {
-        if (fwcfg_acked == TRUE)
+        if (fwcfg_acked)
         {
             epilog_wait_timer();
-            bthc_signal_event(HC_EVENT_EPILOG);
-        }
-        else
-        {
-            bthc_signal_event(HC_EVENT_EXIT);
+            thread_post(hc_cb.worker_thread, event_epilog, NULL);
         }
 
-        pthread_join(hc_cb.worker_thread, NULL);
+        thread_free(hc_cb.worker_thread);
+        hc_cb.worker_thread = NULL;
 
-        if (hc_cb.epilog_timer_created == 1)
+        if (hc_cb.epilog_timer_created)
         {
             timer_delete(hc_cb.epilog_timer_id);
-            hc_cb.epilog_timer_created = 0;
+            hc_cb.epilog_timer_created = false;
         }
     }
 
-    lib_running = 0;
-
     lpm_cleanup();
     userial_close();
     p_hci_if->cleanup();
@@ -428,11 +454,10 @@ static void cleanup( void )
     set_power(BT_VND_PWR_OFF);
     vendor_close();
 
-    fwcfg_acked = FALSE;
+    fwcfg_acked = false;
     bt_hc_cbacks = NULL;
 }
 
-
 static const bt_hc_interface_t bluetoothHCLibInterface = {
     sizeof(bt_hc_interface_t),
     init,
@@ -446,174 +471,6 @@ static const bt_hc_interface_t bluetoothHCLibInterface = {
     tx_hc_cmd,
 };
 
-
-/*******************************************************************************
-**
-** Function        bt_hc_worker_thread
-**
-** Description     Mian worker thread
-**
-** Returns         void *
-**
-*******************************************************************************/
-static void *bt_hc_worker_thread(void *arg)
-{
-    uint16_t events;
-    HC_BT_HDR *p_msg, *p_next_msg;
-    UNUSED(arg);
-
-    ALOGI("bt_hc_worker_thread started");
-    prctl(PR_SET_NAME, (unsigned long)"bt_hc_worker", 0, 0, 0);
-    tx_cmd_pkts_pending = FALSE;
-
-    raise_priority_a2dp(TASK_HIGH_HCI_WORKER);
-
-    while (lib_running)
-    {
-        pthread_mutex_lock(&hc_cb.mutex);
-        while (ready_events == 0)
-        {
-            pthread_cond_wait(&hc_cb.cond, &hc_cb.mutex);
-        }
-        events = ready_events;
-        ready_events = 0;
-        pthread_mutex_unlock(&hc_cb.mutex);
-
-#ifndef HCI_USE_MCT
-        if (events & HC_EVENT_RX)
-        {
-            p_hci_if->rcv();
-
-            if ((tx_cmd_pkts_pending == TRUE) && (num_hci_cmd_pkts > 0))
-            {
-                /* Got HCI Cmd Credits from Controller.
-                 * Prepare to send prior pending Cmd packets in the
-                 * following HC_EVENT_TX session.
-                 */
-                events |= HC_EVENT_TX;
-            }
-        }
-#endif
-
-        if (events & HC_EVENT_PRELOAD)
-        {
-            userial_open(USERIAL_PORT_1);
-            vendor_send_command(BT_VND_OP_FW_CFG, NULL);
-        }
-
-        if (events & HC_EVENT_POSTLOAD)
-        {
-            /* Start from SCO related H/W configuration, if SCO configuration
-             * is required. Then, follow with reading requests of getting
-             * ACL data length for both BR/EDR and LE.
-             */
-            int result = vendor_send_command(BT_VND_OP_SCO_CFG, NULL);
-            if (result == -1)
-                p_hci_if->get_acl_max_len();
-        }
-
-        if (events & HC_EVENT_TX)
-        {
-            /*
-             *  We will go through every packets in the tx queue.
-             *  Fine to clear tx_cmd_pkts_pending.
-             */
-            tx_cmd_pkts_pending = FALSE;
-            HC_BT_HDR * sending_msg_que[64];
-            int sending_msg_count = 0;
-            int sending_hci_cmd_pkts_count = 0;
-            utils_lock();
-            p_next_msg = tx_q.p_first;
-            while (p_next_msg && sending_msg_count <
-                  (int)(sizeof(sending_msg_que)/sizeof(sending_msg_que[0])))
-            {
-                if ((p_next_msg->event & MSG_EVT_MASK)==MSG_STACK_TO_HC_HCI_CMD)
-                {
-                    /*
-                     *  if we have used up controller's outstanding HCI command
-                     *  credits (normally is 1), skip all HCI command packets in
-                     *  the queue.
-                     *  The pending command packets will be sent once controller
-                     *  gives back us credits through CommandCompleteEvent or
-                     *  CommandStatusEvent.
-                     */
-                    if ((tx_cmd_pkts_pending == TRUE) ||
-                        (sending_hci_cmd_pkts_count >= num_hci_cmd_pkts))
-                    {
-                        tx_cmd_pkts_pending = TRUE;
-                        p_next_msg = utils_getnext(p_next_msg);
-                        continue;
-                    }
-                    sending_hci_cmd_pkts_count++;
-                }
-
-                p_msg = p_next_msg;
-                p_next_msg = utils_getnext(p_msg);
-                utils_remove_from_queue_unlocked(&tx_q, p_msg);
-                sending_msg_que[sending_msg_count++] = p_msg;
-            }
-            utils_unlock();
-            int i;
-            for(i = 0; i < sending_msg_count; i++)
-                p_hci_if->send(sending_msg_que[i]);
-            if (tx_cmd_pkts_pending == TRUE)
-                BTHCDBG("Used up Tx Cmd credits");
-
-        }
-
-        if (events & HC_EVENT_LPM_ENABLE)
-        {
-            lpm_enable(TRUE);
-        }
-
-        if (events & HC_EVENT_LPM_DISABLE)
-        {
-            lpm_enable(FALSE);
-        }
-
-        if (events & HC_EVENT_LPM_IDLE_TIMEOUT)
-        {
-            lpm_wake_deassert();
-        }
-
-        if (events & HC_EVENT_LPM_ALLOW_SLEEP)
-        {
-            lpm_allow_bt_device_sleep();
-        }
-
-        if (events & HC_EVENT_LPM_WAKE_DEVICE)
-        {
-            lpm_wake_assert();
-        }
-
-        if (events & HC_EVENT_TX_CMD)
-        {
-            HC_BT_HDR *p_cmd_msg;
-            while ((p_cmd_msg = utils_dequeue(&hc_cb.cmd_q)) != NULL)
-            {
-                if ((0 >= tx_hc_msg(p_cmd_msg)) && bt_hc_cbacks)
-                    bt_hc_cbacks->dealloc(p_cmd_msg);
-            }
-        }
-
-        if (events & HC_EVENT_EPILOG)
-        {
-            vendor_send_command(BT_VND_OP_EPILOG, NULL);
-        }
-
-        if (events & HC_EVENT_EXIT)
-            break;
-    }
-
-    ALOGI("bt_hc_worker_thread exiting");
-    lib_running = 0;
-
-    pthread_exit(NULL);
-
-    return NULL;    // compiler friendly
-}
-
-
 /*******************************************************************************
 **
 ** Function        bt_hc_get_interface
@@ -627,4 +484,3 @@ const bt_hc_interface_t *bt_hc_get_interface(void)
 {
     return &bluetoothHCLibInterface;
 }
-
index d297070..ba6e2a2 100644 (file)
@@ -152,8 +152,6 @@ typedef struct
 **  Externs
 ******************************************************************************/
 
-extern BUFFER_Q tx_q;
-
 uint8_t hci_h4_send_int_cmd(uint16_t opcode, HC_BT_HDR *p_buf, \
                                   tINT_CMD_CBACK p_cback);
 void lpm_wake_assert(void);
@@ -994,9 +992,7 @@ uint8_t hci_h4_send_int_cmd(uint16_t opcode, HC_BT_HDR *p_buf, \
     /* stamp signature to indicate an internal command */
     p_buf->layer_specific = opcode;
 
-    utils_enqueue(&tx_q, (void *) p_buf);
-    bthc_signal_event(HC_EVENT_TX);
-
+    bthc_tx(p_buf);
     return TRUE;
 }
 
index ac4543b..5316326 100644 (file)
@@ -136,8 +136,6 @@ typedef struct
 **  Externs
 ******************************************************************************/
 
-extern BUFFER_Q tx_q;
-
 uint8_t hci_mct_send_int_cmd(uint16_t opcode, HC_BT_HDR *p_buf, \
                                   tINT_CMD_CBACK p_cback);
 void lpm_wake_assert(void);
@@ -253,7 +251,7 @@ uint8_t internal_event_intercept(void)
 
         // Signal TX event so the worker thread can check if it has anything
         // to send
-        bthc_signal_event(HC_EVENT_TX);
+        bthc_tx(NULL);
 
         if (p_cb->int_cmd_rsp_pending > 0)
         {
@@ -292,7 +290,7 @@ uint8_t internal_event_intercept(void)
 
         // Signal TX event so the worker thread can check if it has anything
         // to send
-        bthc_signal_event(HC_EVENT_TX);
+        bthc_tx(NULL);
     }
 
     return FALSE;
@@ -1097,9 +1095,7 @@ uint8_t hci_mct_send_int_cmd(uint16_t opcode, HC_BT_HDR *p_buf, \
     /* stamp signature to indicate an internal command */
     p_buf->layer_specific = opcode;
 
-    utils_enqueue(&tx_q, (void *) p_buf);
-    bthc_signal_event(HC_EVENT_TX);
-
+    bthc_tx(p_buf);
     return TRUE;
 }
 
index cdc6660..71023ba 100644 (file)
@@ -115,7 +115,7 @@ static void lpm_idle_timeout(union sigval arg)
     if ((bt_lpm_cb.state == LPM_ENABLED) && \
         (bt_lpm_cb.wake_state == LPM_WAKE_W4_TIMEOUT))
     {
-        bthc_signal_event(HC_EVENT_LPM_IDLE_TIMEOUT);
+        bthc_idle_timeout();
     }
 }
 
index f186ffa..dde6b95 100644 (file)
@@ -234,7 +234,7 @@ static void *userial_read_thread(void *arg)
         {
             p_buf->len = (uint16_t)rx_length;
             utils_enqueue(&(userial_cb.rx_q), p_buf);
-            bthc_signal_event(HC_EVENT_RX);
+            bthc_rx_ready();
         }
         else /* either 0 or < 0 */
         {
index 3b97f89..c4bd966 100644 (file)
@@ -233,9 +233,7 @@ bool userial_init(void)
 *******************************************************************************/
 bool userial_open(userial_port_t port)
 {
-    struct sched_param param;
-    int policy, result;
-    pthread_attr_t thread_attr;
+    int result;
 
     USERIALDBG("userial_open(port:%d)", port);
 
@@ -277,32 +275,13 @@ bool userial_open(userial_port_t port)
     userial_cb.port = port;
 
     /* Start listening thread */
-    pthread_attr_init(&thread_attr);
-
-    if (pthread_create(&(userial_cb.read_thread), &thread_attr, \
-                       userial_read_thread, NULL) != 0 )
+    if (pthread_create(&userial_cb.read_thread, NULL, userial_read_thread, NULL) != 0)
     {
         ALOGE("pthread_create failed!");
         vendor_send_command(BT_VND_OP_USERIAL_CLOSE, NULL);
         return false;
     }
 
-    if(pthread_getschedparam(userial_cb.read_thread, &policy, &param)==0)
-    {
-        policy = BTHC_LINUX_BASE_POLICY;
-#if (BTHC_LINUX_BASE_POLICY != SCHED_NORMAL)
-        param.sched_priority = BTHC_USERIAL_READ_THREAD_PRIORITY;
-#else
-        param.sched_priority = 0;
-#endif
-        result = pthread_setschedparam(userial_cb.read_thread, policy, &param);
-        if (result != 0)
-        {
-            ALOGW("userial_open: pthread_setschedparam failed (%s)", \
-                  strerror(result));
-        }
-    }
-
     return true;
 }
 
index bfda025..4bad100 100644 (file)
@@ -29,7 +29,7 @@
 
 // TODO: eliminate these three.
 extern tHCI_IF *p_hci_if;
-extern uint8_t fwcfg_acked;
+extern bool fwcfg_acked;
 void lpm_vnd_cback(uint8_t vnd_result);
 
 static const char *VENDOR_LIBRARY_NAME = "libbt-vendor.so";
@@ -177,5 +177,4 @@ static uint8_t transmit_cb(uint16_t opcode, void *buffer, tINT_CMD_CBACK callbac
 // completed. It is safe to call vendor_interface->cleanup() after
 // this callback has been received.
 static void epilog_cb(UNUSED_ATTR bt_vendor_op_result_t result) {
-  bthc_signal_event(HC_EVENT_EXIT);
 }