BlueDroid代码分析之初始化

时间:2022-06-09 03:51:57

安卓蓝牙协议栈初始化

bluedroid协议栈初始化过程如下图所示:

BlueDroid代码分析之初始化

Bluetooth.c是安卓蓝牙的硬件抽象,是BlueDroid的对外接口,供JNI直接调用。bluedroid编译出的库为bluetooth.default.so依赖于libbt-hci.so、libbt-utils.so、libbt-vendor.so等动态库。下面逐一分析安卓是怎么初始化协议栈的!本文是从协议栈bluedroid角度分析的,安卓的framework层次的初始化请参考 

安卓蓝牙协议栈的初始化-java层次

从上图可以看到,协议栈的初始化和enable过程创建了sock_poll_thread ,bt_hc_worker_thread,
btif_task,btu_task.sock_poll_thread跟蓝牙多媒体相关,bt_hc_worker_thread是串口的发送/接收数据进程,btif_task处理用户提交的命令,与HAL 和BTA交互进程,btu_task与L2CAP交互进程。下面我们着重分析下后面的两个进程:
在init的时候会创建btif_task进程,代码如下: btif/src/btif_core.c
bt_status_t btif_init_bluetooth()
{
UINT8 status;
btif_config_init();//创建<span style="font-size: 18px;">sock_poll_thread,并获取配置文件</span>
bte_main_boot_entry();//初始化GKI,加载厂商库和相关配置文件

/* As part of the init, fetch the local BD ADDR */
memset(&btif_local_bd_addr, 0, sizeof(bt_bdaddr_t));
btif_fetch_local_bdaddr(&btif_local_bd_addr); //从配置文件获取本地蓝牙的mac地址

/* start btif task */
status = GKI_create_task(btif_task, BTIF_TASK, BTIF_TASK_STR,
(UINT16 *) ((UINT8 *)btif_task_stack + BTIF_TASK_STACK_SIZE),
sizeof(btif_task_stack)); //创建btif_task进程
if (status != GKI_SUCCESS)
return BT_STATUS_FAIL;

return BT_STATUS_SUCCESS;
}
btif_task代码路径: btif/src/btif_core.c
static void btif_task(UINT32 params)
{
UINT16 event;
BT_HDR *p_msg;

BTIF_TRACE_DEBUG0("btif task starting");

btif_associate_evt();//回调注册的thread_evt_cb,通知ASSOCIATE_JVM事件

for(;;)
{
/* wait for specified events */
event = GKI_wait(0xFFFF, 0); //等待有效的事件,或者有消息发送到本进程时
//在GKI_send_msg最后也会发送event到本线程
/*
* Wait for the trigger to init chip and stack. This trigger will
* be received by btu_task once the UART is opened and ready
*/
if (event == BT_EVT_TRIGGER_STACK_INIT)
{
BTIF_TRACE_DEBUG0("btif_task: received trigger stack init event");
#if (BLE_INCLUDED == TRUE)
btif_dm_load_ble_local_keys();
#endif
BTA_EnableBluetooth(bte_dm_evt);
}

/*
* Failed to initialize controller hardware, reset state and bring
* down all threads
*/
if (event == BT_EVT_HARDWARE_INIT_FAIL)
{
BTIF_TRACE_DEBUG0("btif_task: hardware init failed");
bte_main_disable();
btif_queue_release();
GKI_task_self_cleanup(BTIF_TASK);
bte_main_shutdown();
btif_dut_mode = 0;
btif_core_state = BTIF_CORE_STATE_DISABLED;
HAL_CBACK(bt_hal_cbacks,adapter_state_changed_cb,BT_STATE_OFF);
break;
}

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) //从消息队列中读取消息
{
BTIF_TRACE_VERBOSE1("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_ERROR1("unhandled btif event (%d)", p_msg->event & BT_EVT_MASK);
break;
}

GKI_freebuf(p_msg);
}
}
}

btif_disassociate_evt();

BTIF_TRACE_DEBUG0("btif task exiting");
}
总结:btif_task实际上就是不停得从消息队列中取消息,并执行消息中注册的回调函数的过程
第二个核心进程时在bte_main_enable函数中创建的,代码如下:
void bte_main_enable()
{
APPL_TRACE_DEBUG1("%s", __FUNCTION__);

/* Initialize BTE control block */
BTE_Init();//btu控制块的初始化

lpm_enabled = FALSE;

bte_hci_enable();//初始化厂商库并设置成power_on

GKI_create_task((TASKPTR)btu_task, BTU_TASK, BTE_BTU_TASK_STR,
(UINT16 *) ((UINT8 *)bte_btu_stack + BTE_BTU_STACK_SIZE),
sizeof(bte_btu_stack));//创建第二大核心进程btu_task,主要是与L2CAP层的数据交互

GKI_run(0);
}
BTU_API UINT32 btu_task (UINT32 param){    UINT16           event;    BT_HDR          *p_msg;    UINT8            i;    UINT16           mask;    BOOLEAN          handled;#if (defined(HCISU_H4_INCLUDED) && HCISU_H4_INCLUDED == TRUE)    /* wait an event that HCISU is ready */    BT_TRACE_0(TRACE_LAYER_BTU, TRACE_TYPE_API,                "btu_task pending for preload complete event");    for (;;)    {        event = GKI_wait (0xFFFF, 0); //        if (event & EVENT_MASK(GKI_SHUTDOWN_EVT))        {            /* indicates BT ENABLE abort */            BT_TRACE_0(TRACE_LAYER_BTU, TRACE_TYPE_WARNING,                        "btu_task start abort!");            return (0);        }        else if (event & BT_EVT_PRELOAD_CMPL)        {            break;        }        else        {            BT_TRACE_1(TRACE_LAYER_BTU, TRACE_TYPE_WARNING,                "btu_task ignore evt %04x while pending for preload complete",                event);        }    }    BT_TRACE_0(TRACE_LAYER_BTU, TRACE_TYPE_API,                "btu_task received preload complete event");#endif    /* Initialize the mandatory core stack control blocks       (BTU, BTM, L2CAP, and SDP)     */    btu_init_core(); //初始化协议栈核心,btm l2cap 和sdp    /* Initialize any optional stack components */    BTE_InitStack(); //初始化协议栈profile 比如spp hid dun hfp RFCOMM等#if (defined(BTU_BTA_INCLUDED) && BTU_BTA_INCLUDED == TRUE)    bta_sys_init();      //注册bta系统回调#endif    /* Initialise platform trace levels at this point as BTE_InitStack() and bta_sys_init()     * reset the control blocks and preset the trace level with XXX_INITIAL_TRACE_LEVEL     */#if ( BT_USE_TRACES==TRUE )    BTE_InitTraceLevels();#endif    /* Send a startup evt message to BTIF_TASK to kickstart the init procedure */    GKI_send_event(BTIF_TASK, BT_EVT_TRIGGER_STACK_INIT); //发送BT_EVT_TRIGGER_STACK_INIT事件给btif_task    raise_priority_a2dp(TASK_HIGH_BTU);    /* Wait for, and process, events */    for (;;)    //事件循环。。。    {        event = GKI_wait (0xFFFF, 0);//处理TASK_MBOX_0_EVT_MASK事件        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;                    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 (btu_cb.timer_queue.p_first == NULL)                        {                            GKI_stop_timer(TIMER_0);                        }                        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;                }            }        }//处理TIMER_0_EVT_MASK事件        if (event & TIMER_0_EVT_MASK)        {            TIMER_LIST_ENT  *p_tle;            GKI_update_timer_list (&btu_cb.timer_queue, 1);            while ((btu_cb.timer_queue.p_first) && (!btu_cb.timer_queue.p_first->ticks))            {                p_tle = btu_cb.timer_queue.p_first;                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:                        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 defined(QUICK_TIMER_TICKS_PER_SEC) && (QUICK_TIMER_TICKS_PER_SEC > 0)//处理TIMER_2_EVT_MASK事件        if (event & TIMER_2_EVT_MASK)        {            btu_process_quick_timer_evt();        }#endif#if (RPC_INCLUDED == TRUE)        /* if RPC message queue event *///处理RPCGEN_MSG_EVT事件        if (event & RPCGEN_MSG_EVT)        {            if ((p_msg = (BT_HDR *) GKI_read_mbox(RPCGEN_MSG_MBOX)) != NULL)                RPCT_RpcgenMsg(p_msg);  /* handle RPC message queue */        }#endif#if (defined(BTU_BTA_INCLUDED) && BTU_BTA_INCLUDED == TRUE)//处理TASK_MBOX_2_EVT_MASK事件        if (event & TASK_MBOX_2_EVT_MASK)        {            while ((p_msg = (BT_HDR *) GKI_read_mbox(TASK_MBOX_2)) != NULL)            {                bta_sys_event(p_msg);            }        }//处理TIMER_1_EVT_MASK事件        if (event & TIMER_1_EVT_MASK)        {            bta_sys_timer_update();        }#endif        if (event & EVENT_MASK(APPL_EVT_7))            break;    }    return(0);}总结:btu_task等待并处理如下事件TASK_MBOX_0_EVT_MASKTIMER_0_EVT_MASKTIMER_2_EVT_MASKRPCGEN_MSG_EVTTASK_MBOX_2_EVT_MASKTIMER_1_EVT_MASK处理事件的过程实际上就是调用回调函数的过程,具体过程请参考回调函数的注册!