Loading system/hci/include/bt_hci_bdroid.h +24 −51 Original line number Diff line number Diff line Loading @@ -27,8 +27,7 @@ * ******************************************************************************/ #ifndef BT_HCI_BDROID_H #define BT_HCI_BDROID_H #pragma once #include "bt_hci_lib.h" Loading @@ -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 */ Loading Loading @@ -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 */ Loading @@ -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); system/hci/include/btsnoop.h +2 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,8 @@ #include <stdbool.h> #include "bt_hci_bdroid.h" void btsnoop_open(const char *p_path); void btsnoop_close(void); Loading system/hci/src/bt_hci_bdroid.c +184 −328 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading @@ -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; Loading @@ -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); } /******************************************************************************* Loading @@ -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; } /******************************************************************************* Loading Loading @@ -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; Loading @@ -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; } } Loading @@ -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"); Loading @@ -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; Loading @@ -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; } Loading @@ -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 */ Loading @@ -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(); Loading @@ -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, Loading @@ -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 Loading @@ -627,4 +484,3 @@ const bt_hc_interface_t *bt_hc_get_interface(void) { return &bluetoothHCLibInterface; } system/hci/src/hci_h4.c +1 −5 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; } Loading system/hci/src/hci_mct.c +3 −7 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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) { Loading Loading @@ -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; Loading Loading @@ -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 Loading
system/hci/include/bt_hci_bdroid.h +24 −51 Original line number Diff line number Diff line Loading @@ -27,8 +27,7 @@ * ******************************************************************************/ #ifndef BT_HCI_BDROID_H #define BT_HCI_BDROID_H #pragma once #include "bt_hci_lib.h" Loading @@ -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 */ Loading Loading @@ -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 */ Loading @@ -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);
system/hci/include/btsnoop.h +2 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,8 @@ #include <stdbool.h> #include "bt_hci_bdroid.h" void btsnoop_open(const char *p_path); void btsnoop_close(void); Loading
system/hci/src/bt_hci_bdroid.c +184 −328 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading @@ -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; Loading @@ -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); } /******************************************************************************* Loading @@ -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; } /******************************************************************************* Loading Loading @@ -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; Loading @@ -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; } } Loading @@ -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"); Loading @@ -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; Loading @@ -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; } Loading @@ -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 */ Loading @@ -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(); Loading @@ -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, Loading @@ -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 Loading @@ -627,4 +484,3 @@ const bt_hc_interface_t *bt_hc_get_interface(void) { return &bluetoothHCLibInterface; }
system/hci/src/hci_h4.c +1 −5 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; } Loading
system/hci/src/hci_mct.c +3 −7 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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) { Loading Loading @@ -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; Loading Loading @@ -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