Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 196019e6 authored by Sharvil Nanavati's avatar Sharvil Nanavati
Browse files

Revert "Revert "Clean up messy dispatch in bt_hci_bdroid by using new primitives.""

Original code broke the build for razor-eng, updated the code to fix break.

This reverts commit c8ac41b1.

Change-Id: I2d2f9b5b51b923e3f0e8092b3169ea447193887d
parent 5ef58cc5
Loading
Loading
Loading
Loading
+24 −51
Original line number Diff line number Diff line
@@ -27,8 +27,7 @@
 *
 ******************************************************************************/

#ifndef BT_HCI_BDROID_H
#define BT_HCI_BDROID_H
#pragma once

#include "bt_hci_lib.h"

@@ -40,48 +39,30 @@
**  Constants & Macros
******************************************************************************/

#if __STDC_VERSION__ < 199901L
#  ifndef FALSE
#    define FALSE 0
#  endif

#  ifndef TRUE
#    define TRUE (!FALSE)
#  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
#else
#  include <stdbool.h>
#  ifndef FALSE
#    define FALSE  false
#  endif

#ifndef BTHC_USERIAL_READ_THREAD_PRIORITY
#define BTHC_USERIAL_READ_THREAD_PRIORITY (BTHC_LINUX_BASE_PRIORITY)
#  ifndef TRUE
#    define TRUE   true
#  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 +107,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 +128,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);
+2 −0
Original line number Diff line number Diff line
@@ -2,6 +2,8 @@

#include <stdbool.h>

#include "bt_hci_bdroid.h"

void btsnoop_open(const char *p_path);
void btsnoop_close(void);

+184 −328
Original line number Diff line number Diff line
@@ -29,16 +29,17 @@

#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)
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)
    {
    pthread_mutex_lock(&hc_cb.mutex);
    ready_events |= event;
    pthread_cond_signal(&hc_cb.cond);
    pthread_mutex_unlock(&hc_cb.mutex);
      /*
       *  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);
static void preload(UNUSED_ATTR TRANSAC transac) {
  BTHCDBG("preload");
    bthc_signal_event(HC_EVENT_PRELOAD);
  thread_post(hc_cb.worker_thread, event_preload, NULL);
}


/** Called post stack initialization */
static void postload(TRANSAC transac)
{
    UNUSED(transac);
static void postload(UNUSED_ATTR TRANSAC transac) {
  BTHCDBG("postload");
    bthc_signal_event(HC_EVENT_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);

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)
{
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
    {
  if (state != BT_HC_LOGGING_ON)
    btsnoop_close();
    }
  else if (p_path != NULL)
    btsnoop_open(p_path);

  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)
{
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;
}

/** 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;
}
+1 −5
Original line number Diff line number Diff line
@@ -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;
}

+3 −7
Original line number Diff line number Diff line
@@ -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;
}

Loading