一图解百惑
整个bluedroid可以分为两大模块:BTIF,BTE
BTIF:提供bluedroid对外的接口
BTE:bluedroid的内部处理,又细分为BTA,BTU,BTM和HCI
BTA:bluedroid中各profile的逻辑实现和处理
BTU:承接BTA与HCI
BTM:蓝牙配对与链路管理
HCI:读取或写入数据到蓝牙hw
下面以实际例子来表现个模块间的协作
tv与蓝牙音箱建立连接
上层应用建立连接时候,会调用到btif_av.c中的connect函数
btif_av.c
static bt_status_t connect(bt_bdaddr_t *bd_addr)
{
BTIF_TRACE_EVENT1("%s", __FUNCTION__);
CHECK_BTAV_INIT();
return btif_queue_connect(UUID_SERVCLASS_AUDIO_SOURCE, bd_addr, connect_int);
}
经过内部逻辑处理后,会调用到bta_av_api.c中的BTA_AvOpen函数
void BTA_AvOpen(BD_ADDR bd_addr, tBTA_AV_HNDL handle, BOOLEAN use_rc, tBTA_SEC sec_mask)
170 {
171 tBTA_AV_API_OPEN *p_buf;
172
173 if ((p_buf = (tBTA_AV_API_OPEN *) GKI_getbuf(sizeof(tBTA_AV_API_OPEN))) != NULL)
174 {
175 p_buf->hdr.event = BTA_AV_API_OPEN_EVT;
176 p_buf->hdr.layer_specific = handle;
177 bdcpy(p_buf->bd_addr, bd_addr);
178 p_buf->use_rc = use_rc;
179 p_buf->sec_mask = sec_mask;
180 p_buf->switch_res = BTA_AV_RS_NONE;
181 bta_sys_sendmsg(p_buf);
182 }
183 }
bta_sys_sendmsg最终会将消息发送btu_task.c中的btu_task线程处理
for (;;)
227 {
228 event = GKI_wait (0xFFFF, 0);
229
230 if (event & TASK_MBOX_0_EVT_MASK)
231 {
........
}
.
.
.
if (event & TASK_MBOX_2_EVT_MASK)
549 {
550 while ((p_msg = (BT_HDR *) GKI_read_mbox(TASK_MBOX_2)) != NULL)
551 {
552 bta_sys_event(p_msg);
553 }
554 }
通过bta_sys_event,消息再次转入bta内部处理,最终经过协议栈a2dp和l2cap和BTM的管理,将建立连接的请求通过bte_main.c的bte_main_hci_send发送给hci处理
void bte_main_hci_send (BT_HDR *p_msg, UINT16 event)
506 {
507 UINT16 sub_event = event & BT_SUB_EVT_MASK; /* local controller ID */
508
509 p_msg->event = event;
510
511
512 if((sub_event == LOCAL_BR_EDR_CONTROLLER_ID) || \
513 (sub_event == LOCAL_BLE_CONTROLLER_ID))
514 {
515 if (bt_hc_if)
516 bt_hc_if->transmit_buf((TRANSAC)p_msg, \
517 (char *) (p_msg + 1), \
518 p_msg->len);
519 else
520 GKI_freebuf(p_msg);
521 }
522 else
523 {
524 APPL_TRACE_ERROR0("Invalid Controller ID. Discarding message.");
525 GKI_freebuf(p_msg);
526 }
527 }
static int transmit_buf(TRANSAC transac, char *p_buf, int len)
338 {
339 utils_enqueue(&tx_q, (void *) transac);
340
341 bthc_signal_event(HC_EVENT_TX);
342
343 return BT_HC_STATUS_SUCCESS;
344 }
bt_hc_worker_thread负责处理hci事件:
if (events & HC_EVENT_TX)
529 {
530 /*
531 * We will go through every packets in the tx queue.
532 * Fine to clear tx_cmd_pkts_pending.
533 */
534 tx_cmd_pkts_pending = FALSE;
535 HC_BT_HDR * sending_msg_que[64];
536 int sending_msg_count = 0;
537 int sending_hci_cmd_pkts_count = 0;
538 utils_lock();
539 p_next_msg = tx_q.p_first;
540 while (p_next_msg && sending_msg_count <
541 (int)sizeof(sending_msg_que)/sizeof(sending_msg_que[0]))
542 {
543 if ((p_next_msg->event & MSG_EVT_MASK)==MSG_STACK_TO_HC_HCI_CMD)
544 {
545 /*
546 * if we have used up controller's outstanding HCI command
547 * credits (normally is 1), skip all HCI command packets in
548 * the queue.
549 * The pending command packets will be sent once controller
550 * gives back us credits through CommandCompleteEvent or
551 * CommandStatusEvent.
552 */
553 if ((tx_cmd_pkts_pending == TRUE) ||
554 (sending_hci_cmd_pkts_count >= num_hci_cmd_pkts))
555 {
556 tx_cmd_pkts_pending = TRUE;
557 p_next_msg = utils_getnext(p_next_msg);
558 continue;
559 }
560 sending_hci_cmd_pkts_count++;
561 }
562
563 p_msg = p_next_msg;
564 p_next_msg = utils_getnext(p_msg);
565 utils_remove_from_queue_unlocked(&tx_q, p_msg);
566 sending_msg_que[sending_msg_count++] = p_msg;
567 }
utils_unlock();
569 int i;
570 for(i = 0; i < sending_msg_count; i++)
571 p_hci_if->send(sending_msg_que[i]);//将数据发送到bt driver中
572 if (tx_cmd_pkts_pending == TRUE)
573 BTHCDBG("Used up Tx Cmd credits");
574
575 }