From 3f9fbe74c1d6e774d3f21275515c7b895715aec5 Mon Sep 17 00:00:00 2001 From: Sharvil Nanavati Date: Sat, 5 Jul 2014 21:21:38 -0700 Subject: [PATCH] Clean up messy dispatch in bt_hci_bdroid by using new primitives. 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 | 58 +---- hci/include/btsnoop.h | 2 + hci/src/bt_hci_bdroid.c | 512 ++++++++++++++++---------------------------- hci/src/hci_h4.c | 6 +- hci/src/hci_mct.c | 10 +- hci/src/lpm.c | 2 +- hci/src/userial.c | 2 +- hci/src/userial_mct.c | 25 +-- hci/src/vendor.c | 3 +- 9 files changed, 206 insertions(+), 414 deletions(-) diff --git a/hci/include/bt_hci_bdroid.h b/hci/include/bt_hci_bdroid.h index bb285d9e0..85b287061 100644 --- a/hci/include/bt_hci_bdroid.h +++ b/hci/include/bt_hci_bdroid.h @@ -27,8 +27,7 @@ * ******************************************************************************/ -#ifndef BT_HCI_BDROID_H -#define BT_HCI_BDROID_H +#pragma once #include "bt_hci_lib.h" @@ -41,47 +40,20 @@ ******************************************************************************/ #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); diff --git a/hci/include/btsnoop.h b/hci/include/btsnoop.h index 4f2d23bda..5dedf6861 100644 --- a/hci/include/btsnoop.h +++ b/hci/include/btsnoop.h @@ -2,6 +2,8 @@ #include +#include "bt_hci_bdroid.h" + void btsnoop_open(const char *p_path); void btsnoop_close(void); diff --git a/hci/src/bt_hci_bdroid.c b/hci/src/bt_hci_bdroid.c index 93266af75..174cc1f1f 100644 --- a/hci/src/bt_hci_bdroid.c +++ b/hci/src/bt_hci_bdroid.c @@ -29,16 +29,17 @@ #include #include -#include + +#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 #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, ¶m)==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, ¶m); - 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; } - diff --git a/hci/src/hci_h4.c b/hci/src/hci_h4.c index d29707079..ba6e2a2bc 100644 --- a/hci/src/hci_h4.c +++ b/hci/src/hci_h4.c @@ -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; } diff --git a/hci/src/hci_mct.c b/hci/src/hci_mct.c index ac4543bc3..5316326f1 100644 --- a/hci/src/hci_mct.c +++ b/hci/src/hci_mct.c @@ -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; } diff --git a/hci/src/lpm.c b/hci/src/lpm.c index cdc66609d..71023ba6e 100644 --- a/hci/src/lpm.c +++ b/hci/src/lpm.c @@ -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(); } } diff --git a/hci/src/userial.c b/hci/src/userial.c index f186ffaab..dde6b9551 100644 --- a/hci/src/userial.c +++ b/hci/src/userial.c @@ -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 */ { diff --git a/hci/src/userial_mct.c b/hci/src/userial_mct.c index 3b97f89f4..c4bd96649 100644 --- a/hci/src/userial_mct.c +++ b/hci/src/userial_mct.c @@ -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, ¶m)==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, ¶m); - if (result != 0) - { - ALOGW("userial_open: pthread_setschedparam failed (%s)", \ - strerror(result)); - } - } - return true; } diff --git a/hci/src/vendor.c b/hci/src/vendor.c index bfda0254d..4bad100c1 100644 --- a/hci/src/vendor.c +++ b/hci/src/vendor.c @@ -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); } -- 2.11.0