bluedroid协议栈初始化过程如下图所示:
Bluetooth.c是安卓蓝牙的硬件抽象,是BlueDroid的对外接口,供JNI直接调用。bluedroid编译出的库为bluetooth.default.so依赖于libbt-hci.so、libbt-utils.so、libbt-vendor.so等动态库。下面逐一分析安卓是怎么初始化协议栈的!本文是从协议栈bluedroid角度分析的,安卓的framework层次的初始化请参考
btif_task,btu_task.sock_poll_thread跟蓝牙多媒体相关,bt_hc_worker_thread是串口的发送/接收数据进程,btif_task处理用户提交的命令,与HAL 和BTA交互进程,btu_task与L2CAP交互进程。下面我们着重分析下后面的两个进程:从上图可以看到,协议栈的初始化和enable过程创建了sock_poll_thread ,bt_hc_worker_thread,
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; }
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"); }
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_MASK TIMER_0_EVT_MASK TIMER_2_EVT_MASK RPCGEN_MSG_EVT TASK_MBOX_2_EVT_MASK TIMER_1_EVT_MASK 处理事件的过程实际上就是调用回调函数的过程,具体过程请参考回调函数的注册!