Replace mailboxes with fixed queues.

Also refactored btu_task a bit.
diff --git a/bta/sys/bta_sys_main.c b/bta/sys/bta_sys_main.c
index adcb4f4..550c0e1 100644
--- a/bta/sys/bta_sys_main.c
+++ b/bta/sys/bta_sys_main.c
@@ -21,12 +21,15 @@
  *  This is the main implementation file for the BTA system manager.
  *
  ******************************************************************************/
+#define LOG_TAG "bta_sys_main"
+#include <cutils/log.h>
 
 #include "btm_api.h"
 #include "bta_api.h"
 #include "bta_sys.h"
 #include "bta_sys_int.h"
 
+#include "fixed_queue.h"
 #include "gki.h"
 #include "ptim.h"
 #include <string.h>
@@ -45,6 +48,9 @@
 UINT8 appl_trace_level = BT_TRACE_LEVEL_WARNING; //APPL_INITIAL_TRACE_LEVEL;
 UINT8 btif_trace_level = BT_TRACE_LEVEL_WARNING;
 
+// Communication queue between btu_task and bta.
+extern fixed_queue_t *btu_bta_msg_queue;
+
 static const tBTA_SYS_REG bta_sys_hw_reg =
 {
     bta_sys_sm_execute,
@@ -156,6 +162,7 @@
 BTA_API void bta_sys_init(void)
 {
     memset(&bta_sys_cb, 0, sizeof(tBTA_SYS_CB));
+
     ptim_init(&bta_sys_cb.ptim_cb, BTA_SYS_TIMER_PERIOD, BTA_TIMER);
     bta_sys_cb.task_id = GKI_get_taskid();
     appl_trace_level = APPL_INITIAL_TRACE_LEVEL;
@@ -579,7 +586,9 @@
 *******************************************************************************/
 void bta_sys_sendmsg(void *p_msg)
 {
-    GKI_send_msg(bta_sys_cb.task_id, BTA_MBOX, p_msg);
+    fixed_queue_enqueue(btu_bta_msg_queue, p_msg);
+    // Signal the target thread work is ready.
+    GKI_send_event(BTU_TASK, (UINT16)EVENT_MASK(BTA_MBOX));
 }
 
 /*******************************************************************************
diff --git a/btif/src/btif_core.c b/btif/src/btif_core.c
index 384b58d..ff41af8 100644
--- a/btif/src/btif_core.c
+++ b/btif/src/btif_core.c
@@ -41,6 +41,7 @@
 #include "btif_api.h"
 #include "bt_utils.h"
 #include "bta_api.h"
+#include "fixed_queue.h"
 #include "gki.h"
 #include "btu.h"
 #include "bte.h"
@@ -127,9 +128,13 @@
 /* sends message to btif task */
 static void btif_sendmsg(void *p_msg);
 
+static fixed_queue_t *btif_msg_queue;
+
 /************************************************************************************
 **  Externs
 ************************************************************************************/
+extern fixed_queue_t *btu_hci_msg_queue;
+
 extern void bte_load_did_conf(const char *p_path);
 
 /** TODO: Move these to _common.h */
@@ -322,24 +327,20 @@
         if (event & EVENT_MASK(GKI_SHUTDOWN_EVT))
             break;
 
-        if(event & TASK_MBOX_1_EVT_MASK)
-        {
-            while((p_msg = GKI_read_mbox(BTU_BTIF_MBOX)) != NULL)
+        while ((p_msg = fixed_queue_try_dequeue(btif_msg_queue)) != NULL) {
+            BTIF_TRACE_VERBOSE("btif task fetched event %x", p_msg->event);
+
+            switch (p_msg->event)
             {
-                BTIF_TRACE_VERBOSE("btif task fetched event %x", p_msg->event);
-
-                switch (p_msg->event)
-                {
-                    case BT_EVT_CONTEXT_SWITCH_EVT:
-                        btif_context_switched(p_msg);
-                        break;
-                    default:
-                        BTIF_TRACE_ERROR("unhandled btif event (%d)", p_msg->event & BT_EVT_MASK);
-                        break;
-                }
-
-                GKI_freebuf(p_msg);
+                case BT_EVT_CONTEXT_SWITCH_EVT:
+                    btif_context_switched(p_msg);
+                    break;
+                default:
+                    BTIF_TRACE_ERROR("unhandled btif event (%d)", p_msg->event & BT_EVT_MASK);
+                    break;
             }
+
+            GKI_freebuf(p_msg);
         }
     }
 
@@ -361,7 +362,9 @@
 
 void btif_sendmsg(void *p_msg)
 {
-    GKI_send_msg(BTIF_TASK, BTU_BTIF_MBOX, p_msg);
+    fixed_queue_enqueue(btif_msg_queue, p_msg);
+    // Signal the target thread work is ready.
+    GKI_send_event(BTIF_TASK, (UINT16)EVENT_MASK(BTU_BTIF_MBOX));
 }
 
 static void btif_fetch_local_bdaddr(bt_bdaddr_t *local_addr)
@@ -477,6 +480,9 @@
 bt_status_t btif_init_bluetooth()
 {
     UINT8 status;
+
+    btif_msg_queue = fixed_queue_new(SIZE_MAX);
+
     btif_config_init();
     bte_main_boot_entry();
 
@@ -783,6 +789,8 @@
 
     bt_utils_cleanup();
 
+    fixed_queue_free(btif_msg_queue, NULL);
+
     BTIF_TRACE_DEBUG("%s done", __FUNCTION__);
 
     return BT_STATUS_SUCCESS;
diff --git a/btif/src/btif_media_task.c b/btif/src/btif_media_task.c
index b85589c..d1d8d56 100644
--- a/btif/src/btif_media_task.c
+++ b/btif/src/btif_media_task.c
@@ -38,6 +38,7 @@
 #include <errno.h>
 
 #include "bt_target.h"
+#include "fixed_queue.h"
 #include "gki.h"
 #include "bta_api.h"
 #include "btu.h"
@@ -301,6 +302,8 @@
 static int media_task_running = MEDIA_TASK_STATE_OFF;
 static UINT64 last_frame_us = 0;
 
+fixed_queue_t *btif_media_cmd_msg_queue;
+fixed_queue_t *btif_media_data_msg_queue;
 
 /*****************************************************************************
  **  Local functions
@@ -772,6 +775,9 @@
 
     APPL_TRACE_EVENT("## A2DP START MEDIA TASK ##");
 
+    btif_media_cmd_msg_queue = fixed_queue_new(SIZE_MAX);
+    btif_media_data_msg_queue = fixed_queue_new(SIZE_MAX);
+
     /* start a2dp media task */
     retval = GKI_create_task((TASKPTR)btif_media_task, A2DP_MEDIA_TASK,
                 A2DP_MEDIA_TASK_TASK_STR,
@@ -804,6 +810,9 @@
 {
     APPL_TRACE_EVENT("## A2DP STOP MEDIA TASK ##");
     GKI_destroy_task(BT_MEDIA_TASK);
+
+    fixed_queue_free(btif_media_cmd_msg_queue, NULL);
+    fixed_queue_free(btif_media_data_msg_queue, NULL);
 }
 
 /*****************************************************************************
@@ -935,7 +944,9 @@
 
     p_buf->event = BTIF_MEDIA_AUDIO_SINK_CLEAR_TRACK;
 
-    GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
+    fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf);
+    // Signal the target thread work is ready.
+    GKI_send_event(BT_MEDIA_TASK, (UINT16)EVENT_MASK(BTIF_MEDIA_TASK_CMD_MBOX));
     return TRUE;
 }
 /*******************************************************************************
@@ -961,7 +972,9 @@
 
     p_buf->event = BTIF_MEDIA_AUDIO_SINK_STOP_DECODING;
 
-    GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
+    fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf);
+    // Signal the target thread work is ready.
+    GKI_send_event(BT_MEDIA_TASK, (UINT16)EVENT_MASK(BTIF_MEDIA_TASK_CMD_MBOX));
     return TRUE;
 }
 
@@ -988,7 +1001,9 @@
 
     p_buf->event = BTIF_MEDIA_AUDIO_SINK_START_DECODING;
 
-    GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
+    fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf);
+    // Signal the target thread work is ready.
+    GKI_send_event(BT_MEDIA_TASK, (UINT16)EVENT_MASK(BTIF_MEDIA_TASK_CMD_MBOX));
     return TRUE;
 }
 
@@ -1019,7 +1034,9 @@
     memcpy(p_buf->codec_info,p_av, AVDT_CODEC_SIZE);
     p_buf->hdr.event = BTIF_MEDIA_AUDIO_SINK_CFG_UPDATE;
 
-    GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
+    fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf);
+    // Signal the target thread work is ready.
+    GKI_send_event(BT_MEDIA_TASK, (UINT16)EVENT_MASK(BTIF_MEDIA_TASK_CMD_MBOX));
 }
 
 /*****************************************************************************
@@ -1372,23 +1389,14 @@
 
         VERBOSE("================= MEDIA TASK EVENT %d ===============", event);
 
-        if (event & BTIF_MEDIA_TASK_CMD)
-        {
-            /* Process all messages in the queue */
-            while ((p_msg = (BT_HDR *) GKI_read_mbox(BTIF_MEDIA_TASK_CMD_MBOX)) != NULL)
-            {
-                btif_media_task_handle_cmd(p_msg);
-            }
+        /* Process all messages in the queue */
+        while ((p_msg = (BT_HDR *)fixed_queue_try_dequeue(btif_media_cmd_msg_queue)) != NULL) {
+            btif_media_task_handle_cmd(p_msg);
         }
 
-        if (event & BTIF_MEDIA_TASK_DATA)
-        {
-            VERBOSE("================= Received Media Packets %d ===============", event);
-            /* Process all messages in the queue */
-            while ((p_msg = (BT_HDR *) GKI_read_mbox(BTIF_MEDIA_TASK_DATA_MBOX)) != NULL)
-            {
-                btif_media_task_handle_media(p_msg);
-            }
+        /* Process all messages in the queue */
+        while ((p_msg = (BT_HDR *)fixed_queue_try_dequeue(btif_media_data_msg_queue)) != NULL) {
+            btif_media_task_handle_media(p_msg);
         }
 
         if (event & BTIF_MEDIA_AA_TASK_TIMER)
@@ -1449,7 +1457,9 @@
 
     p_buf->event = Evt;
 
-    GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
+    fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf);
+    // Signal the target thread work is ready.
+    GKI_send_event(BT_MEDIA_TASK, (UINT16)EVENT_MASK(BTIF_MEDIA_TASK_CMD_MBOX));
     return TRUE;
 }
 
@@ -1625,7 +1635,9 @@
     memcpy(p_buf, p_msg, sizeof(tBTIF_MEDIA_INIT_AUDIO));
     p_buf->hdr.event = BTIF_MEDIA_SBC_ENC_INIT;
 
-    GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
+    fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf);
+    // Signal the target thread work is ready.
+    GKI_send_event(BT_MEDIA_TASK, (UINT16)EVENT_MASK(BTIF_MEDIA_TASK_CMD_MBOX));
     return TRUE;
 }
 
@@ -1649,7 +1661,9 @@
     memcpy(p_buf, p_msg, sizeof(tBTIF_MEDIA_UPDATE_AUDIO));
     p_buf->hdr.event = BTIF_MEDIA_SBC_ENC_UPDATE;
 
-    GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
+    fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf);
+    // Signal the target thread work is ready.
+    GKI_send_event(BT_MEDIA_TASK, (UINT16)EVENT_MASK(BTIF_MEDIA_TASK_CMD_MBOX));
     return TRUE;
 }
 
@@ -1673,7 +1687,10 @@
     memcpy(p_buf, p_msg, sizeof(tBTIF_MEDIA_INIT_AUDIO_FEEDING));
     p_buf->hdr.event = BTIF_MEDIA_AUDIO_FEEDING_INIT;
 
-    GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
+    fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf);
+    // Signal the target thread work is ready.
+    GKI_send_event(BT_MEDIA_TASK, (UINT16)EVENT_MASK(BTIF_MEDIA_TASK_CMD_MBOX));
+
     return TRUE;
 }
 
@@ -1697,7 +1714,10 @@
 
     p_buf->event = BTIF_MEDIA_START_AA_TX;
 
-    GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
+    fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf);
+    // Signal the target thread work is ready.
+    GKI_send_event(BT_MEDIA_TASK, (UINT16)EVENT_MASK(BTIF_MEDIA_TASK_CMD_MBOX));
+
     return TRUE;
 }
 
@@ -1720,8 +1740,11 @@
 
     p_buf->event = BTIF_MEDIA_STOP_AA_TX;
 
-    GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
-    return TRUE;
+    fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf);
+    // Signal the target thread work is ready.
+    GKI_send_event(BT_MEDIA_TASK, (UINT16)EVENT_MASK(BTIF_MEDIA_TASK_CMD_MBOX));
+
+   return TRUE;
 }
 /*******************************************************************************
  **
@@ -1746,7 +1769,9 @@
 
     p_buf->event = BTIF_MEDIA_FLUSH_AA_RX;
 
-    GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
+    fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf);
+    // Signal the target thread work is ready.
+    GKI_send_event(BT_MEDIA_TASK, (UINT16)EVENT_MASK(BTIF_MEDIA_TASK_CMD_MBOX));
     return TRUE;
 }
 
@@ -1769,7 +1794,10 @@
 
     p_buf->event = BTIF_MEDIA_FLUSH_AA_TX;
 
-    GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
+    fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf);
+    // Signal the target thread work is ready.
+    GKI_send_event(BT_MEDIA_TASK, (UINT16)EVENT_MASK(BTIF_MEDIA_TASK_CMD_MBOX));
+
     return TRUE;
 }
 /*******************************************************************************
diff --git a/gki/common/gki.h b/gki/common/gki.h
index 0e6f892..8cc12e5 100644
--- a/gki/common/gki.h
+++ b/gki/common/gki.h
@@ -151,8 +151,6 @@
 
 /* To send buffers and events between tasks
 */
-GKI_API extern void   *GKI_read_mbox  (UINT8);
-GKI_API extern void    GKI_send_msg   (UINT8, UINT8, void *);
 GKI_API extern UINT8   GKI_send_event (UINT8, UINT16);
 
 
diff --git a/gki/common/gki_buffer.c b/gki/common/gki_buffer.c
index c85acf6..0c17523 100644
--- a/gki/common/gki_buffer.c
+++ b/gki/common/gki_buffer.c
@@ -159,16 +159,6 @@
     UINT8   i, tt, mb;
     tGKI_COM_CB *p_cb = &gki_cb.com;
 
-    /* Initialize mailboxes */
-    for (tt = 0; tt < GKI_MAX_TASKS; tt++)
-    {
-        for (mb = 0; mb < NUM_TASK_MBOX; mb++)
-        {
-            p_cb->OSTaskQFirst[tt][mb] = NULL;
-            p_cb->OSTaskQLast [tt][mb] = NULL;
-        }
-    }
-
     for (tt = 0; tt < GKI_NUM_TOTAL_BUF_POOLS; tt++)
     {
         p_cb->pool_start[tt] = NULL;
@@ -558,12 +548,6 @@
 
     p_hdr = (BUFFER_HDR_T *) ((UINT8 *)p_buf - BUFFER_HDR_SIZE);
 
-    if (p_hdr->status != BUF_STATUS_UNLINKED)
-    {
-        GKI_exception(GKI_ERROR_FREEBUF_BUF_LINKED, "Freeing Linked Buf");
-        return;
-    }
-
     if (p_hdr->q_id >= GKI_NUM_TOTAL_BUF_POOLS)
     {
         GKI_exception(GKI_ERROR_FREEBUF_BAD_QID, "Bad Buf QId");
@@ -662,106 +646,6 @@
 
 /*******************************************************************************
 **
-** Function         GKI_send_msg
-**
-** Description      Called by applications to send a buffer to a task
-**
-** Returns          Nothing
-**
-*******************************************************************************/
-void GKI_send_msg (UINT8 task_id, UINT8 mbox, void *msg)
-{
-    BUFFER_HDR_T    *p_hdr;
-    tGKI_COM_CB *p_cb = &gki_cb.com;
-
-    /* If task non-existant or not started, drop buffer */
-    if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX) || (p_cb->OSRdyTbl[task_id] == TASK_DEAD))
-    {
-        GKI_exception(GKI_ERROR_SEND_MSG_BAD_DEST, "Sending to unknown dest");
-        GKI_freebuf (msg);
-        return;
-    }
-
-#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
-    if (gki_chk_buf_damage(msg))
-    {
-        GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Send - Buffer corrupted");
-        return;
-    }
-#endif
-
-    p_hdr = (BUFFER_HDR_T *) ((UINT8 *) msg - BUFFER_HDR_SIZE);
-
-    if (p_hdr->status != BUF_STATUS_UNLINKED)
-    {
-        GKI_exception(GKI_ERROR_SEND_MSG_BUF_LINKED, "Send - buffer linked");
-        return;
-    }
-
-    GKI_disable();
-
-    if (p_cb->OSTaskQFirst[task_id][mbox])
-        p_cb->OSTaskQLast[task_id][mbox]->p_next = p_hdr;
-    else
-        p_cb->OSTaskQFirst[task_id][mbox] = p_hdr;
-
-    p_cb->OSTaskQLast[task_id][mbox] = p_hdr;
-
-    p_hdr->p_next = NULL;
-    p_hdr->status = BUF_STATUS_QUEUED;
-    p_hdr->task_id = task_id;
-
-
-    GKI_enable();
-
-    GKI_send_event(task_id, (UINT16)EVENT_MASK(mbox));
-
-    return;
-}
-
-/*******************************************************************************
-**
-** Function         GKI_read_mbox
-**
-** Description      Called by applications to read a buffer from one of
-**                  the task mailboxes.  A task can only read its own mailbox.
-**
-** Parameters:      mbox  - (input) mailbox ID to read (0, 1, 2, or 3)
-**
-** Returns          NULL if the mailbox was empty, else the address of a buffer
-**
-*******************************************************************************/
-void *GKI_read_mbox (UINT8 mbox)
-{
-    UINT8           task_id = GKI_get_taskid();
-    void            *p_buf = NULL;
-    BUFFER_HDR_T    *p_hdr;
-
-    if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX))
-        return (NULL);
-
-    GKI_disable();
-
-    if (gki_cb.com.OSTaskQFirst[task_id][mbox])
-    {
-        p_hdr = gki_cb.com.OSTaskQFirst[task_id][mbox];
-        gki_cb.com.OSTaskQFirst[task_id][mbox] = p_hdr->p_next;
-
-        p_hdr->p_next = NULL;
-        p_hdr->status = BUF_STATUS_UNLINKED;
-
-        p_buf = (UINT8 *)p_hdr + BUFFER_HDR_SIZE;
-    }
-
-    GKI_enable();
-
-    return (p_buf);
-}
-
-
-
-/*******************************************************************************
-**
 ** Function         GKI_enqueue
 **
 ** Description      Enqueue a buffer at the tail of the queue
diff --git a/gki/common/gki_common.h b/gki/common/gki_common.h
index 5083bd2..64c9f69 100644
--- a/gki/common/gki_common.h
+++ b/gki/common/gki_common.h
@@ -295,13 +295,6 @@
     INT32   OSTaskTmr3R [GKI_MAX_TASKS];
 #endif
 
-
-
-    /* Buffer related variables
-    */
-    BUFFER_HDR_T    *OSTaskQFirst[GKI_MAX_TASKS][NUM_TASK_MBOX]; /* array of pointers to the first event in the task mailbox */
-    BUFFER_HDR_T    *OSTaskQLast [GKI_MAX_TASKS][NUM_TASK_MBOX]; /* array of pointers to the last event in the task mailbox */
-
     /* Define the buffer pool management variables
     */
     FREE_QUEUE_T    freeq[GKI_NUM_TOTAL_BUF_POOLS];
diff --git a/gki/ulinux/gki_ulinux.c b/gki/ulinux/gki_ulinux.c
index a387eb4..ec2d98b 100644
--- a/gki/ulinux/gki_ulinux.c
+++ b/gki/ulinux/gki_ulinux.c
@@ -655,15 +655,6 @@
            no need to call GKI_disable() here as we know that we will have some events as we've been waking
            up after condition pending or timeout */
 
-        if (gki_cb.com.OSTaskQFirst[rtask][0])
-            gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_0_EVT_MASK;
-        if (gki_cb.com.OSTaskQFirst[rtask][1])
-            gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_1_EVT_MASK;
-        if (gki_cb.com.OSTaskQFirst[rtask][2])
-            gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_2_EVT_MASK;
-        if (gki_cb.com.OSTaskQFirst[rtask][3])
-            gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_3_EVT_MASK;
-
         if (gki_cb.com.OSRdyTbl[rtask] == TASK_DEAD)
         {
             gki_cb.com.OSWaitEvt[rtask] = 0;
diff --git a/main/bte_main.c b/main/bte_main.c
index a6fffd2..2ae5020 100755
--- a/main/bte_main.c
+++ b/main/bte_main.c
@@ -86,6 +86,12 @@
 BOOLEAN hci_save_log = FALSE; /* save a copy of the log before starting again */
 char hci_logfile[256] = HCI_LOGGING_FILENAME;
 
+// Communication queue between btu_task and bta.
+fixed_queue_t *btu_bta_msg_queue;
+
+// Communication queue between btu_task and hci.
+fixed_queue_t *btu_hci_msg_queue;
+
 /*******************************************************************************
 **  Static variables
 *******************************************************************************/
@@ -215,6 +221,9 @@
 {
     APPL_TRACE_DEBUG("%s", __FUNCTION__);
 
+    btu_bta_msg_queue = fixed_queue_new(SIZE_MAX);
+    btu_hci_msg_queue = fixed_queue_new(SIZE_MAX);
+
     /* Initialize BTE control block */
     BTE_StartUp();
 
@@ -632,7 +641,10 @@
 }
 
 static void dump_upbound_data_to_btu(fixed_queue_t *queue, UNUSED_ATTR void *context) {
-    GKI_send_msg (BTU_TASK, BTU_HCI_RCV_MBOX, fixed_queue_dequeue(queue));
+    fixed_queue_enqueue(btu_hci_msg_queue, fixed_queue_dequeue(queue));
+    // Signal the target thread work is ready.
+    GKI_send_event(BTU_TASK, (UINT16)EVENT_MASK(BTU_HCI_RCV_MBOX));
+
 }
 
 /******************************************************************************
@@ -659,7 +671,9 @@
 {
     if (!all_fragments_sent)
     {
-        GKI_send_msg (BTU_TASK, BTU_HCI_RCV_MBOX, p_buf);
+        fixed_queue_enqueue(btu_hci_msg_queue, p_buf);
+        // Signal the target thread work is ready.
+        GKI_send_event(BTU_TASK, (UINT16)EVENT_MASK(BTU_HCI_RCV_MBOX));
     }
     else
     {
diff --git a/stack/btu/btu_init.c b/stack/btu/btu_init.c
index 0fdd6b4..e84edd4 100644
--- a/stack/btu/btu_init.c
+++ b/stack/btu/btu_init.c
@@ -27,6 +27,7 @@
 #include <string.h>
 #include "dyn_mem.h"
 
+#include "fixed_queue.h"
 #include "btu.h"
 #include "btm_int.h"
 #include "sdpint.h"
@@ -40,6 +41,10 @@
 #endif
 #endif
 
+
+extern fixed_queue_t *btu_hci_msg_queue;
+extern fixed_queue_t *btu_bta_msg_queue;
+
 extern void PLATFORM_DisableHciTransport(UINT8 bDisable);
 /*****************************************************************************
 **                          V A R I A B L E S                                *
@@ -131,6 +136,8 @@
     while (!GKI_queue_is_empty(&btu_cb.hci_cmd_cb[i].cmd_cmpl_q))
       GKI_freebuf(GKI_dequeue(&btu_cb.hci_cmd_cb[i].cmd_cmpl_q));
   }
+  fixed_queue_free(btu_bta_msg_queue, NULL);
+  fixed_queue_free(btu_hci_msg_queue, NULL);
 }
 
 
@@ -179,7 +186,7 @@
 {
     BT_TRACE(TRACE_LAYER_BTM, TRACE_TYPE_DEBUG, "btu_uipc_rx_cback event 0x%x, len %d, offset %d",
 		p_msg->event, p_msg->len, p_msg->offset);
-    GKI_send_msg(BTU_TASK, BTU_HCI_RCV_MBOX, p_msg);
-
+    fixed_queue_enqueue(btu_hci_msg_queue, p_msg);
+    // Signal the target thread work is ready.
+    GKI_send_event(BTU_TASK, (UINT16)EVENT_MASK(BTU_HCI_RCV_MBOX));
 }
-
diff --git a/stack/btu/btu_task.c b/stack/btu/btu_task.c
index 2880223..92e9872 100644
--- a/stack/btu/btu_task.c
+++ b/stack/btu/btu_task.c
@@ -28,13 +28,20 @@
  *
  ******************************************************************************/
 
+#include <cutils/log.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 
 #include "bt_target.h"
-#include "gki.h"
+#include "bt_trace.h"
 #include "bt_types.h"
+#include "bt_utils.h"
+#include "btm_api.h"
+#include "btm_int.h"
+#include "btu.h"
+#include "fixed_queue.h"
+#include "gki.h"
 #include "hcimsgs.h"
 #include "l2c_int.h"
 #include "btu.h"
@@ -48,9 +55,6 @@
 #include "port_ext.h"
 #endif
 
-#include "btm_api.h"
-#include "btm_int.h"
-
 #if (defined(EVAL) && EVAL == TRUE)
 #include "btu_eval.h"
 #endif
@@ -72,8 +76,6 @@
 
 #endif /* OBX */
 
-#include "bt_trace.h"
-
 /* BTE application task */
 #if APPL_INCLUDED == TRUE
 #include "bte_appl.h"
@@ -111,7 +113,6 @@
 #include "mca_int.h"
 #endif
 
-
 #if (defined(BTU_BTA_INCLUDED) && BTU_BTA_INCLUDED == TRUE)
 #include "bta_sys.h"
 #endif
@@ -141,10 +142,332 @@
 tBTU_CB  btu_cb;
 #endif
 
+// Communication queue between btu_task and bta.
+extern fixed_queue_t *btu_bta_msg_queue;
+
+// Communication queue between btu_task and hci.
+extern fixed_queue_t *btu_hci_msg_queue;
+
 
 /* Define a function prototype to allow a generic timeout handler */
 typedef void (tUSER_TIMEOUT_FUNC) (TIMER_LIST_ENT *p_tle);
 
+static void btu_hci_msg_process(BT_HDR *p_msg) {
+    /* Determine the input message type. */
+    switch (p_msg->event & BT_EVT_MASK)
+    {
+        case BT_EVT_TO_BTU_HCI_ACL:
+            /* All Acl Data goes to L2CAP */
+            l2c_rcv_acl_data (p_msg);
+            break;
+
+        case BT_EVT_TO_BTU_L2C_SEG_XMIT:
+            /* L2CAP segment transmit complete */
+            l2c_link_segments_xmitted (p_msg);
+            break;
+
+        case BT_EVT_TO_BTU_HCI_SCO:
+#if BTM_SCO_INCLUDED == TRUE
+            btm_route_sco_data (p_msg);
+            break;
+#endif
+
+        case BT_EVT_TO_BTU_HCI_EVT:
+            btu_hcif_process_event ((UINT8)(p_msg->event & BT_SUB_EVT_MASK), p_msg);
+            GKI_freebuf(p_msg);
+
+#if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE)
+            /* If host receives events which it doesn't response to, */
+            /* host should start idle timer to enter sleep mode.     */
+            btu_check_bt_sleep ();
+#endif
+            break;
+
+        case BT_EVT_TO_BTU_HCI_CMD:
+            btu_hcif_send_cmd ((UINT8)(p_msg->event & BT_SUB_EVT_MASK), p_msg);
+            break;
+
+#if (defined(OBX_INCLUDED) && OBX_INCLUDED == TRUE)
+#if (defined(OBX_SERVER_INCLUDED) && OBX_SERVER_INCLUDED == TRUE)
+        case BT_EVT_TO_OBX_SR_MSG:
+            obx_sr_proc_evt((tOBX_PORT_EVT *)(p_msg + 1));
+            GKI_freebuf (p_msg);
+            break;
+
+        case BT_EVT_TO_OBX_SR_L2C_MSG:
+            obx_sr_proc_l2c_evt((tOBX_L2C_EVT_MSG *)(p_msg + 1));
+            GKI_freebuf (p_msg);
+            break;
+#endif
+
+#if (defined(OBX_CLIENT_INCLUDED) && OBX_CLIENT_INCLUDED == TRUE)
+        case BT_EVT_TO_OBX_CL_MSG:
+            obx_cl_proc_evt((tOBX_PORT_EVT *)(p_msg + 1));
+            GKI_freebuf (p_msg);
+            break;
+
+        case BT_EVT_TO_OBX_CL_L2C_MSG:
+            obx_cl_proc_l2c_evt((tOBX_L2C_EVT_MSG *)(p_msg + 1));
+            GKI_freebuf (p_msg);
+            break;
+#endif
+
+#if (defined(BIP_INCLUDED) && BIP_INCLUDED == TRUE)
+        case BT_EVT_TO_BIP_CMDS :
+            bip_proc_btu_event(p_msg);
+            GKI_freebuf (p_msg);
+            break;
+#endif /* BIP */
+#if (BPP_SND_INCLUDED == TRUE || BPP_INCLUDED == TRUE)
+        case BT_EVT_TO_BPP_PR_CMDS:
+            bpp_pr_proc_event(p_msg);
+            GKI_freebuf (p_msg);
+            break;
+        case BT_EVT_TO_BPP_SND_CMDS:
+            bpp_snd_proc_event(p_msg);
+            GKI_freebuf (p_msg);
+            break;
+
+#endif /* BPP */
+
+#endif /* OBX */
+
+#if (defined(SAP_SERVER_INCLUDED) && SAP_SERVER_INCLUDED == TRUE)
+        case BT_EVT_TO_BTU_SAP :
+            sap_proc_btu_event(p_msg);
+            GKI_freebuf (p_msg);
+            break;
+#endif /* SAP */
+#if (defined(GAP_CONN_INCLUDED) && GAP_CONN_INCLUDED == TRUE && GAP_CONN_POST_EVT_INCLUDED == TRUE)
+        case BT_EVT_TO_GAP_MSG :
+            gap_proc_btu_event(p_msg);
+            GKI_freebuf (p_msg);
+            break;
+#endif
+            // NOTE: The timer calls below may not be sent by HCI.
+        case BT_EVT_TO_START_TIMER :
+            /* Start free running 1 second timer for list management */
+            GKI_start_timer (TIMER_0, GKI_SECS_TO_TICKS (1), TRUE);
+            GKI_freebuf (p_msg);
+            break;
+
+        case BT_EVT_TO_STOP_TIMER:
+            if (GKI_timer_queue_is_empty(&btu_cb.timer_queue)) {
+                GKI_stop_timer(TIMER_0);
+            }
+            GKI_freebuf (p_msg);
+            break;
+
+                    case BT_EVT_TO_START_TIMER_ONESHOT:
+                        if (!GKI_timer_queue_is_empty(&btu_cb.timer_queue_oneshot)) {
+                            TIMER_LIST_ENT *tle = GKI_timer_getfirst(&btu_cb.timer_queue_oneshot);
+                            // Start non-repeating timer.
+                            GKI_start_timer(TIMER_3, tle->ticks, FALSE);
+                        } else {
+                            BTM_TRACE_WARNING("Oneshot timer queue empty when received start request");
+                        }
+                        GKI_freebuf(p_msg);
+                        break;
+
+                    case BT_EVT_TO_STOP_TIMER_ONESHOT:
+                        if (GKI_timer_queue_is_empty(&btu_cb.timer_queue_oneshot)) {
+                            GKI_stop_timer(TIMER_3);
+                        } else {
+                            BTM_TRACE_WARNING("Oneshot timer queue not empty when received stop request");
+                        }
+                        GKI_freebuf (p_msg);
+                        break;
+
+#if defined(QUICK_TIMER_TICKS_PER_SEC) && (QUICK_TIMER_TICKS_PER_SEC > 0)
+        case BT_EVT_TO_START_QUICK_TIMER :
+            GKI_start_timer (TIMER_2, QUICK_TIMER_TICKS, TRUE);
+            GKI_freebuf (p_msg);
+            break;
+#endif
+
+        default:;
+            int i = 0;
+            uint16_t mask = (UINT16) (p_msg->event & BT_EVT_MASK);
+            BOOLEAN handled = FALSE;
+
+            for (; !handled && i < BTU_MAX_REG_EVENT; i++)
+            {
+                if (btu_cb.event_reg[i].event_cb == NULL)
+                    continue;
+
+                if (mask == btu_cb.event_reg[i].event_range)
+                {
+                    if (btu_cb.event_reg[i].event_cb)
+                    {
+                        btu_cb.event_reg[i].event_cb(p_msg);
+                        handled = TRUE;
+                    }
+                }
+            }
+
+            if (handled == FALSE)
+                GKI_freebuf (p_msg);
+
+            break;
+    }
+
+}
+
+static void btu_timer_process() {
+    GKI_update_timer_list (&btu_cb.timer_queue, 1);
+
+    while (!GKI_timer_queue_is_empty(&btu_cb.timer_queue)) {
+        TIMER_LIST_ENT *p_tle = GKI_timer_getfirst(&btu_cb.timer_queue);
+        if (p_tle->ticks != 0)
+            break;
+
+        GKI_remove_from_timer_list (&btu_cb.timer_queue, p_tle);
+
+        switch (p_tle->event)
+        {
+            case BTU_TTYPE_BTM_DEV_CTL:
+                btm_dev_timeout(p_tle);
+                break;
+
+            case BTU_TTYPE_BTM_ACL:
+                btm_acl_timeout(p_tle);
+                break;
+
+            case BTU_TTYPE_L2CAP_LINK:
+            case BTU_TTYPE_L2CAP_CHNL:
+            case BTU_TTYPE_L2CAP_HOLD:
+            case BTU_TTYPE_L2CAP_INFO:
+            case BTU_TTYPE_L2CAP_FCR_ACK:
+
+                l2c_process_timeout (p_tle);
+                break;
+
+            case BTU_TTYPE_SDP:
+                sdp_conn_timeout ((tCONN_CB *)p_tle->param);
+                break;
+
+            case BTU_TTYPE_BTM_RMT_NAME:
+                btm_inq_rmt_name_failed();
+                break;
+
+#if (defined(RFCOMM_INCLUDED) && RFCOMM_INCLUDED == TRUE)
+            case BTU_TTYPE_RFCOMM_MFC:
+            case BTU_TTYPE_RFCOMM_PORT:
+                rfcomm_process_timeout (p_tle);
+                break;
+
+#endif /* If defined(RFCOMM_INCLUDED) && RFCOMM_INCLUDED == TRUE */
+
+#if ((defined(BNEP_INCLUDED) && BNEP_INCLUDED == TRUE))
+            case BTU_TTYPE_BNEP:
+                bnep_process_timeout(p_tle);
+                break;
+#endif
+
+
+#if (defined(AVDT_INCLUDED) && AVDT_INCLUDED == TRUE)
+            case BTU_TTYPE_AVDT_CCB_RET:
+            case BTU_TTYPE_AVDT_CCB_RSP:
+            case BTU_TTYPE_AVDT_CCB_IDLE:
+            case BTU_TTYPE_AVDT_SCB_TC:
+                avdt_process_timeout(p_tle);
+                break;
+#endif
+
+#if (defined(OBX_INCLUDED) && OBX_INCLUDED == TRUE)
+#if (defined(OBX_CLIENT_INCLUDED) && OBX_CLIENT_INCLUDED == TRUE)
+            case BTU_TTYPE_OBX_CLIENT_TO:
+                obx_cl_timeout(p_tle);
+                break;
+#endif
+#if (defined(OBX_SERVER_INCLUDED) && OBX_SERVER_INCLUDED == TRUE)
+            case BTU_TTYPE_OBX_SERVER_TO:
+                obx_sr_timeout(p_tle);
+                break;
+
+            case BTU_TTYPE_OBX_SVR_SESS_TO:
+                obx_sr_sess_timeout(p_tle);
+                break;
+#endif
+#endif
+
+#if (defined(SAP_SERVER_INCLUDED) && SAP_SERVER_INCLUDED == TRUE)
+            case BTU_TTYPE_SAP_TO:
+                sap_process_timeout(p_tle);
+                break;
+#endif
+
+            case BTU_TTYPE_BTU_CMD_CMPL:
+                btu_hcif_cmd_timeout((UINT8)(p_tle->event - BTU_TTYPE_BTU_CMD_CMPL));
+                break;
+
+#if (defined(HID_HOST_INCLUDED) && HID_HOST_INCLUDED == TRUE)
+            case BTU_TTYPE_HID_HOST_REPAGE_TO :
+                hidh_proc_repage_timeout(p_tle);
+                break;
+#endif
+
+#if (defined(BLE_INCLUDED) && BLE_INCLUDED == TRUE)
+            case BTU_TTYPE_BLE_INQUIRY:
+            case BTU_TTYPE_BLE_GAP_LIM_DISC:
+            case BTU_TTYPE_BLE_RANDOM_ADDR:
+            case BTU_TTYPE_BLE_GAP_FAST_ADV:
+            case BTU_TTYPE_BLE_OBSERVE:
+                btm_ble_timeout(p_tle);
+                break;
+
+            case BTU_TTYPE_ATT_WAIT_FOR_RSP:
+                gatt_rsp_timeout(p_tle);
+                break;
+
+            case BTU_TTYPE_ATT_WAIT_FOR_IND_ACK:
+                gatt_ind_ack_timeout(p_tle);
+                break;
+#if (defined(SMP_INCLUDED) && SMP_INCLUDED == TRUE)
+            case BTU_TTYPE_SMP_PAIRING_CMD:
+                smp_rsp_timeout(p_tle);
+                break;
+#endif
+
+#endif
+
+#if (MCA_INCLUDED == TRUE)
+            case BTU_TTYPE_MCA_CCB_RSP:
+                mca_process_timeout(p_tle);
+                break;
+#endif
+            case BTU_TTYPE_USER_FUNC:
+                {
+                    tUSER_TIMEOUT_FUNC  *p_uf = (tUSER_TIMEOUT_FUNC *)p_tle->param;
+                    (*p_uf)(p_tle);
+                }
+                break;
+
+            default:;
+                int i = 0;
+                BOOLEAN handled = FALSE;
+
+                for (; !handled && i < BTU_MAX_REG_TIMER; i++)
+                {
+                    if (btu_cb.timer_reg[i].timer_cb == NULL)
+                        continue;
+                    if (btu_cb.timer_reg[i].p_tle == p_tle)
+                    {
+                        btu_cb.timer_reg[i].timer_cb(p_tle);
+                        handled = TRUE;
+                    }
+                }
+                break;
+        }
+    }
+
+    /* if timer list is empty stop periodic GKI timer */
+    if (btu_cb.timer_queue.p_first == NULL)
+    {
+        GKI_stop_timer(TIMER_0);
+    }
+}
+
 /*******************************************************************************
 **
 ** Function         btu_task
@@ -216,352 +539,29 @@
     /* Send a startup evt message to BTIF_TASK to kickstart the init procedure */
     GKI_send_event(BTIF_TASK, BT_EVT_TRIGGER_STACK_INIT);
 
-    prctl(PR_SET_NAME, (unsigned long)"BTU TASK", 0, 0, 0);
-
     raise_priority_a2dp(TASK_HIGH_BTU);
 
     /* Wait for, and process, events */
-    for (;;)
-    {
+    for (;;) {
         event = GKI_wait (0xFFFF, 0);
 
-        if (event & TASK_MBOX_0_EVT_MASK)
-        {
-            /* Process all messages in the queue */
-            while ((p_msg = (BT_HDR *) GKI_read_mbox (BTU_HCI_RCV_MBOX)) != NULL)
-            {
-                /* Determine the input message type. */
-                switch (p_msg->event & BT_EVT_MASK)
-                {
-                    case BT_EVT_TO_BTU_HCI_ACL:
-                        /* All Acl Data goes to L2CAP */
-                        l2c_rcv_acl_data (p_msg);
-                        break;
+        while ((p_msg = (BT_HDR *)fixed_queue_try_dequeue(btu_hci_msg_queue)) != NULL)
+            btu_hci_msg_process(p_msg);
 
-                    case BT_EVT_TO_BTU_L2C_SEG_XMIT:
-                        /* L2CAP segment transmit complete */
-                        l2c_link_segments_xmitted (p_msg);
-                        break;
-
-                    case BT_EVT_TO_BTU_HCI_SCO:
-#if BTM_SCO_INCLUDED == TRUE
-                        btm_route_sco_data (p_msg);
-                        break;
-#endif
-
-                    case BT_EVT_TO_BTU_HCI_EVT:
-                        btu_hcif_process_event ((UINT8)(p_msg->event & BT_SUB_EVT_MASK), p_msg);
-                        GKI_freebuf(p_msg);
-
-#if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE)
-                        /* If host receives events which it doesn't response to, */
-                        /* host should start idle timer to enter sleep mode.     */
-                        btu_check_bt_sleep ();
-#endif
-                        break;
-
-                    case BT_EVT_TO_BTU_HCI_CMD:
-                        btu_hcif_send_cmd ((UINT8)(p_msg->event & BT_SUB_EVT_MASK), p_msg);
-                        break;
-
-#if (defined(OBX_INCLUDED) && OBX_INCLUDED == TRUE)
-#if (defined(OBX_SERVER_INCLUDED) && OBX_SERVER_INCLUDED == TRUE)
-                    case BT_EVT_TO_OBX_SR_MSG:
-                        obx_sr_proc_evt((tOBX_PORT_EVT *)(p_msg + 1));
-                        GKI_freebuf (p_msg);
-                        break;
-
-                    case BT_EVT_TO_OBX_SR_L2C_MSG:
-                        obx_sr_proc_l2c_evt((tOBX_L2C_EVT_MSG *)(p_msg + 1));
-                        GKI_freebuf (p_msg);
-                        break;
-#endif
-
-#if (defined(OBX_CLIENT_INCLUDED) && OBX_CLIENT_INCLUDED == TRUE)
-                    case BT_EVT_TO_OBX_CL_MSG:
-                        obx_cl_proc_evt((tOBX_PORT_EVT *)(p_msg + 1));
-                        GKI_freebuf (p_msg);
-                        break;
-
-                    case BT_EVT_TO_OBX_CL_L2C_MSG:
-                        obx_cl_proc_l2c_evt((tOBX_L2C_EVT_MSG *)(p_msg + 1));
-                        GKI_freebuf (p_msg);
-                        break;
-#endif
-
-#if (defined(BIP_INCLUDED) && BIP_INCLUDED == TRUE)
-                    case BT_EVT_TO_BIP_CMDS :
-                        bip_proc_btu_event(p_msg);
-                        GKI_freebuf (p_msg);
-                        break;
-#endif /* BIP */
-#if (BPP_SND_INCLUDED == TRUE || BPP_INCLUDED == TRUE)
-                    case BT_EVT_TO_BPP_PR_CMDS:
-                        bpp_pr_proc_event(p_msg);
-                        GKI_freebuf (p_msg);
-                        break;
-                    case BT_EVT_TO_BPP_SND_CMDS:
-                        bpp_snd_proc_event(p_msg);
-                        GKI_freebuf (p_msg);
-                        break;
-
-#endif /* BPP */
-
-#endif /* OBX */
-
-#if (defined(SAP_SERVER_INCLUDED) && SAP_SERVER_INCLUDED == TRUE)
-                    case BT_EVT_TO_BTU_SAP :
-                        sap_proc_btu_event(p_msg);
-                        GKI_freebuf (p_msg);
-                        break;
-#endif /* SAP */
-#if (defined(GAP_CONN_INCLUDED) && GAP_CONN_INCLUDED == TRUE && GAP_CONN_POST_EVT_INCLUDED == TRUE)
-                    case BT_EVT_TO_GAP_MSG :
-                        gap_proc_btu_event(p_msg);
-                        GKI_freebuf (p_msg);
-                        break;
-#endif
-                    case BT_EVT_TO_START_TIMER :
-                        /* Start free running 1 second timer for list management */
-                        GKI_start_timer (TIMER_0, GKI_SECS_TO_TICKS (1), TRUE);
-                        GKI_freebuf (p_msg);
-                        break;
-
-                    case BT_EVT_TO_STOP_TIMER:
-                        if (GKI_timer_queue_is_empty(&btu_cb.timer_queue)) {
-                            GKI_stop_timer(TIMER_0);
-                        }
-                        GKI_freebuf (p_msg);
-                        break;
-
-                    case BT_EVT_TO_START_TIMER_ONESHOT:
-                        if (!GKI_timer_queue_is_empty(&btu_cb.timer_queue_oneshot)) {
-                            TIMER_LIST_ENT *tle = GKI_timer_getfirst(&btu_cb.timer_queue_oneshot);
-                            // Start non-repeating timer.
-                            GKI_start_timer(TIMER_3, tle->ticks, FALSE);
-                        } else {
-                            BTM_TRACE_WARNING("Oneshot timer queue empty when received start request");
-                        }
-                        GKI_freebuf(p_msg);
-                        break;
-
-                    case BT_EVT_TO_STOP_TIMER_ONESHOT:
-                        if (GKI_timer_queue_is_empty(&btu_cb.timer_queue_oneshot)) {
-                            GKI_stop_timer(TIMER_3);
-                        } else {
-                            BTM_TRACE_WARNING("Oneshot timer queue not empty when received stop request");
-                        }
-                        GKI_freebuf (p_msg);
-                        break;
-
-#if defined(QUICK_TIMER_TICKS_PER_SEC) && (QUICK_TIMER_TICKS_PER_SEC > 0)
-                    case BT_EVT_TO_START_QUICK_TIMER :
-                        GKI_start_timer (TIMER_2, QUICK_TIMER_TICKS, TRUE);
-                        GKI_freebuf (p_msg);
-                        break;
-#endif
-
-                    default:
-                        i = 0;
-                        mask = (UINT16) (p_msg->event & BT_EVT_MASK);
-                        handled = FALSE;
-
-                        for (; !handled && i < BTU_MAX_REG_EVENT; i++)
-                        {
-                            if (btu_cb.event_reg[i].event_cb == NULL)
-                                continue;
-
-                            if (mask == btu_cb.event_reg[i].event_range)
-                            {
-                                if (btu_cb.event_reg[i].event_cb)
-                                {
-                                    btu_cb.event_reg[i].event_cb(p_msg);
-                                    handled = TRUE;
-                                }
-                            }
-                        }
-
-                        if (handled == FALSE)
-                            GKI_freebuf (p_msg);
-
-                        break;
-                }
-            }
-        }
-
-
-        if (event & TIMER_0_EVT_MASK) {
-            GKI_update_timer_list (&btu_cb.timer_queue, 1);
-
-            while (!GKI_timer_queue_is_empty(&btu_cb.timer_queue)) {
-                TIMER_LIST_ENT *p_tle = GKI_timer_getfirst(&btu_cb.timer_queue);
-                if (p_tle->ticks != 0)
-                    break;
-
-                GKI_remove_from_timer_list(&btu_cb.timer_queue, p_tle);
-
-                switch (p_tle->event) {
-                    case BTU_TTYPE_BTM_DEV_CTL:
-                        btm_dev_timeout(p_tle);
-                        break;
-
-                    case BTU_TTYPE_BTM_ACL:
-                        btm_acl_timeout(p_tle);
-                        break;
-
-                    case BTU_TTYPE_L2CAP_LINK:
-                    case BTU_TTYPE_L2CAP_CHNL:
-                    case BTU_TTYPE_L2CAP_HOLD:
-                    case BTU_TTYPE_L2CAP_INFO:
-                    case BTU_TTYPE_L2CAP_FCR_ACK:
-                        l2c_process_timeout (p_tle);
-                        break;
-
-                    case BTU_TTYPE_SDP:
-                        sdp_conn_timeout ((tCONN_CB *)p_tle->param);
-                        break;
-
-                    case BTU_TTYPE_BTM_RMT_NAME:
-                        btm_inq_rmt_name_failed();
-                        break;
-
-#if (defined(RFCOMM_INCLUDED) && RFCOMM_INCLUDED == TRUE)
-                    case BTU_TTYPE_RFCOMM_MFC:
-                    case BTU_TTYPE_RFCOMM_PORT:
-                        rfcomm_process_timeout (p_tle);
-                        break;
-
-#endif /* If defined(RFCOMM_INCLUDED) && RFCOMM_INCLUDED == TRUE */
-
-#if ((defined(BNEP_INCLUDED) && BNEP_INCLUDED == TRUE))
-                    case BTU_TTYPE_BNEP:
-                        bnep_process_timeout(p_tle);
-                        break;
-#endif
-
-
-#if (defined(AVDT_INCLUDED) && AVDT_INCLUDED == TRUE)
-                    case BTU_TTYPE_AVDT_CCB_RET:
-                    case BTU_TTYPE_AVDT_CCB_RSP:
-                    case BTU_TTYPE_AVDT_CCB_IDLE:
-                    case BTU_TTYPE_AVDT_SCB_TC:
-                        avdt_process_timeout(p_tle);
-                        break;
-#endif
-
-#if (defined(OBX_INCLUDED) && OBX_INCLUDED == TRUE)
-#if (defined(OBX_CLIENT_INCLUDED) && OBX_CLIENT_INCLUDED == TRUE)
-                    case BTU_TTYPE_OBX_CLIENT_TO:
-                        obx_cl_timeout(p_tle);
-                        break;
-#endif
-#if (defined(OBX_SERVER_INCLUDED) && OBX_SERVER_INCLUDED == TRUE)
-                    case BTU_TTYPE_OBX_SERVER_TO:
-                        obx_sr_timeout(p_tle);
-                        break;
-
-                    case BTU_TTYPE_OBX_SVR_SESS_TO:
-                        obx_sr_sess_timeout(p_tle);
-                        break;
-#endif
-#endif
-
-#if (defined(SAP_SERVER_INCLUDED) && SAP_SERVER_INCLUDED == TRUE)
-                    case BTU_TTYPE_SAP_TO:
-                        sap_process_timeout(p_tle);
-                        break;
-#endif
-
-                    case BTU_TTYPE_BTU_CMD_CMPL:
-                        btu_hcif_cmd_timeout((UINT8)(p_tle->event - BTU_TTYPE_BTU_CMD_CMPL));
-                        break;
-
-#if (defined(HID_HOST_INCLUDED) && HID_HOST_INCLUDED == TRUE)
-                    case BTU_TTYPE_HID_HOST_REPAGE_TO :
-                        hidh_proc_repage_timeout(p_tle);
-                        break;
-#endif
-
-#if (defined(BLE_INCLUDED) && BLE_INCLUDED == TRUE)
-                    case BTU_TTYPE_BLE_INQUIRY:
-                    case BTU_TTYPE_BLE_GAP_LIM_DISC:
-                    case BTU_TTYPE_BLE_GAP_FAST_ADV:
-                    case BTU_TTYPE_BLE_OBSERVE:
-                        btm_ble_timeout(p_tle);
-                        break;
-
-                    case BTU_TTYPE_ATT_WAIT_FOR_RSP:
-                        gatt_rsp_timeout(p_tle);
-                        break;
-
-                    case BTU_TTYPE_ATT_WAIT_FOR_IND_ACK:
-                        gatt_ind_ack_timeout(p_tle);
-                        break;
-#if (defined(SMP_INCLUDED) && SMP_INCLUDED == TRUE)
-                    case BTU_TTYPE_SMP_PAIRING_CMD:
-                        smp_rsp_timeout(p_tle);
-                        break;
-#endif
-
-#endif
-
-#if (MCA_INCLUDED == TRUE)
-                    case BTU_TTYPE_MCA_CCB_RSP:
-                        mca_process_timeout(p_tle);
-                        break;
-#endif
-                    case BTU_TTYPE_USER_FUNC:
-                        {
-                            tUSER_TIMEOUT_FUNC  *p_uf = (tUSER_TIMEOUT_FUNC *)p_tle->param;
-                            (*p_uf)(p_tle);
-                        }
-                        break;
-
-                    default:
-                        i = 0;
-                        handled = FALSE;
-
-                        for (; !handled && i < BTU_MAX_REG_TIMER; i++)
-                        {
-                            if (btu_cb.timer_reg[i].timer_cb == NULL)
-                                continue;
-                            if (btu_cb.timer_reg[i].p_tle == p_tle)
-                            {
-                                btu_cb.timer_reg[i].timer_cb(p_tle);
-                                handled = TRUE;
-                            }
-                        }
-                        break;
-                }
-            }
-
-            /* if timer list is empty stop periodic GKI timer */
-            if (btu_cb.timer_queue.p_first == NULL)
-            {
-                GKI_stop_timer(TIMER_0);
-            }
-        }
+        if (event & TIMER_0_EVT_MASK)
+            btu_timer_process();
 
 #if defined(QUICK_TIMER_TICKS_PER_SEC) && (QUICK_TIMER_TICKS_PER_SEC > 0)
         if (event & TIMER_2_EVT_MASK)
-        {
             btu_process_quick_timer_evt();
-        }
 #endif
 
 #if (defined(BTU_BTA_INCLUDED) && BTU_BTA_INCLUDED == TRUE)
-        if (event & TASK_MBOX_2_EVT_MASK)
-        {
-            while ((p_msg = (BT_HDR *) GKI_read_mbox(TASK_MBOX_2)) != NULL)
-            {
-                bta_sys_event(p_msg);
-            }
-        }
+        while ((p_msg = (BT_HDR *)fixed_queue_try_dequeue(btu_bta_msg_queue)) != NULL)
+            bta_sys_event(p_msg);
 
         if (event & TIMER_1_EVT_MASK)
-        {
             bta_sys_timer_update();
-        }
 #endif
 
         if (event & TIMER_3_EVT_MASK) {
@@ -645,7 +645,9 @@
             if ((p_msg = (BT_HDR *)GKI_getbuf(BT_HDR_SIZE)) != NULL)
             {
                 p_msg->event = BT_EVT_TO_START_TIMER;
-                GKI_send_msg (BTU_TASK, TASK_MBOX_0, p_msg);
+                fixed_queue_enqueue(btu_hci_msg_queue, p_msg);
+                // Signal the target thread work is ready.
+                GKI_send_event(BTU_TASK, (UINT16)EVENT_MASK(BTU_HCI_RCV_MBOX));
             }
         }
         else
@@ -701,7 +703,9 @@
         if ((p_msg = (BT_HDR *)GKI_getbuf(BT_HDR_SIZE)) != NULL)
         {
             p_msg->event = BT_EVT_TO_STOP_TIMER;
-            GKI_send_msg (BTU_TASK, TASK_MBOX_0, p_msg);
+            fixed_queue_enqueue(btu_hci_msg_queue, p_msg);
+            // Signal the target thread work is ready.
+            GKI_send_event(BTU_TASK, (UINT16)EVENT_MASK(BTU_HCI_RCV_MBOX));
         }
     }
     else
@@ -744,7 +748,9 @@
             if ((p_msg = (BT_HDR *)GKI_getbuf(BT_HDR_SIZE)) != NULL)
             {
                 p_msg->event = BT_EVT_TO_START_QUICK_TIMER;
-                GKI_send_msg (BTU_TASK, TASK_MBOX_0, p_msg);
+                fixed_queue_enqueue(btu_hci_msg_queue, p_msg);
+                // Signal the target thread work is ready.
+                GKI_send_event(BTU_TASK, (UINT16)EVENT_MASK(BTU_HCI_RCV_MBOX));
             }
         }
         else
@@ -862,7 +868,9 @@
         BT_HDR *p_msg = (BT_HDR *)GKI_getbuf(BT_HDR_SIZE);
         if (p_msg != NULL) {
             p_msg->event = BT_EVT_TO_START_TIMER_ONESHOT;
-            GKI_send_msg (BTU_TASK, TASK_MBOX_0, p_msg);
+            fixed_queue_enqueue(btu_hci_msg_queue, p_msg);
+            // Signal the target thread work is ready.
+            GKI_send_event(BTU_TASK, (UINT16)EVENT_MASK(BTU_HCI_RCV_MBOX));
         }
     } else {
         TIMER_LIST_ENT *tle = GKI_timer_getfirst(&btu_cb.timer_queue_oneshot);
@@ -880,7 +888,9 @@
         BT_HDR *p_msg = (BT_HDR *)GKI_getbuf(BT_HDR_SIZE);
         if (p_msg != NULL) {
             p_msg->event = BT_EVT_TO_STOP_TIMER_ONESHOT;
-            GKI_send_msg (BTU_TASK, TASK_MBOX_0, p_msg);
+            fixed_queue_enqueue(btu_hci_msg_queue, p_msg);
+            // Signal the target thread work is ready.
+            GKI_send_event(BTU_TASK, (UINT16)EVENT_MASK(BTU_HCI_RCV_MBOX));
         }
     } else {
         if (GKI_timer_queue_is_empty(&btu_cb.timer_queue_oneshot)) {
diff --git a/stack/gap/gap_conn.c b/stack/gap/gap_conn.c
index 61f8892..d546d77 100644
--- a/stack/gap/gap_conn.c
+++ b/stack/gap/gap_conn.c
@@ -20,6 +20,7 @@
 #include "bt_target.h"
 #include "bt_utils.h"
 #include "btu.h"
+#include "fixed_queue.h"
 #include "gap_int.h"
 #include "l2cdefs.h"
 #include "l2c_int.h"
@@ -27,6 +28,7 @@
 #if GAP_CONN_INCLUDED == TRUE
 #include "btm_int.h"
 
+extern fixed_queue_t *btu_hci_msg_queue;
 /********************************************************************************/
 /*              L O C A L    F U N C T I O N     P R O T O T Y P E S            */
 /********************************************************************************/
@@ -1215,7 +1217,10 @@
         p_msg->offset = 0;
         p_msg->layer_specific = gap_handle;
 
-        GKI_send_msg(BTU_TASK, BTU_HCI_RCV_MBOX, p_msg);
+        fixed_queue_enqueue(btu_hci_msg_queue, p_msg);
+        // Signal the target thread work is ready.
+        GKI_send_event(BTU_TASK, (UINT16)EVENT_MASK(BTU_HCI_RCV_MBOX));
+
     }
     else
     {