1 Android system will try to reconnect paired A2DP device automatically after BT enable.
123456789
04-2501:56:31.080D/BluetoothAdapterService(2093):AutoConnectingA2DPProfilewithdevice50:C9:71:0D:D2:D9packages/apps/Bluetooth/jni/com_android_bluetooth_a2dp.cppstaticjbooleanconnectA2dpNative(JNIEnv*env,jobjectobject,jbyteArrayaddress)constbt_interface_t*btInf=getBluetoothInterface();constbtav_interface_t*sBluetoothA2dpInterface=(btav_interface_t*)btInf->get_profile_interface(BT_PROFILE_ADVANCED_AUDIO_ID);status=sBluetoothA2dpInterface->connect((bt_bdaddr_t*)addr)external/bluetooth/bluedroid/btif/src/btif_av.cbtif_queue_connect(UUID_SERVCLASS_AUDIO_SOURCE,bd_addr,connect_int);//This will trigger an event in btu_task, now the caller thread returned.GKI_send_msg(BTIF_TASK,BTU_BTIF_MBOX,p_msg);
2 This will later trigger a A2DP server event API_CONNECT_REQ_EVT in state CCB_IDLE_ST:
3 A2DP server handle this event in bellow two actions:
123456789101112
external/bluetooth/bluedroid/stack/avdt/avdt_ccb.c129constUINT8avdt_ccb_st_idle[][AVDT_CCB_NUM_COLS]={130/* Event Action 1 Action 2 Next state */139/* API_CONNECT_REQ_EVT */{AVDT_CCB_SET_CONN,AVDT_CCB_CHAN_OPEN,AVDT_CCB_OPENING_ST},//3.1 Set CCB variables associated with AVDT_ConnectReq().996voidavdt_ccb_set_conn(tAVDT_CCB*p_ccb,tAVDT_CCB_EVT*p_data)BTM_SetSecurityLevel(TRUE,"",BTM_SEC_SERVICE_AVDTP,p_data->connect.sec_mask,AVDT_PSM,BTM_SEC_PROTO_AVDT,AVDT_CHAN_SIG);//3.2 initiate a signaling channel connection.87voidavdt_ccb_chan_open(tAVDT_CCB*p_ccb,tAVDT_CCB_EVT*p_data)BTM_SetOutService(p_ccb->peer_addr,BTM_SEC_SERVICE_AVDTP,AVDT_CHAN_SIG);avdt_ad_open_req(AVDT_CHAN_SIG,p_ccb,NULL,AVDT_INT);
4 How L2CAP handle this channel connection:
12345678910111213
external/bluetooth/bluedroid/stack/l2cap/l2c_api.c229UINT16L2CA_ErtmConnectReq(UINT16psm,BD_ADDRp_bd_addr,tL2CAP_ERTM_INFO*p_ertm_info)p_lcb=l2cu_allocate_lcb(p_bd_addr,FALSE);l2cu_create_conn(p_lcb);//This function initiates an acl connection via HCI2180BOOLEANl2cu_create_conn_after_switch(tL2C_LCB*p_lcb)//external/bluetooth/bluedroid/stack/hcic/hcicmds.cbtsnd_hcic_create_conn(p_lcb->remote_bd_addr,HCI_PKT_TYPES_MASK_DM1+HCI_PKT_TYPES_MASK_DH1,page_scan_rep_mode,page_scan_mode,clock_offset,allow_switch));HCI_CMD_TO_LOWER(p_buf);//external/bluetooth/bluedroid/main/bte_main.cbt_hc_if->transmit_buf((TRANSAC)p_msg,\(char*)(p_msg+1),\p_msg->len);utils_enqueue(&tx_q,(void*)transac);bthc_signal_event(HC_EVENT_TX);btu_start_timer(&p_lcb->timer_entry,BTU_TTYPE_L2CAP_LINK,L2CAP_LINK_CONNECT_TOUT);
5 This command will trigger connection establish process between local and remote device, accomplished by a event-driven state machine in BT stack.
Item B. a2dp_write data path:
1 A2DP client writes to A2DP data socket will trigger API_WRITE_REQ_EVT in SCB_STREAM_ST state:
12345
05-0201:14:03.134I/bt-avp(2139):SCBhdl=1event=1/API_WRITE_REQ_EVTstate=SCB_STREAM_ST394/* state table for streaming state */395constUINT8avdt_scb_st_stream[][AVDT_SCB_NUM_COLS]={396/* Event Action 1 Action 2 Next state */398/* API_WRITE_REQ_EVT */{AVDT_SCB_HDL_WRITE_REQ,AVDT_SCB_CHK_SND_PKT,AVDT_SCB_STREAM_ST},
2 A2DP server handle this with bellow two actions:
12345678
//2.1 build a new media packet and stores it in the SCB.external/bluetooth/bluedroid/stack/avdt/avdt_scb_act.c1320voidavdt_scb_hdl_write_req(tAVDT_SCB*p_scb,tAVDT_SCB_EVT*p_data)//2.2 send this stored media packet to L2CAP layer.1921voidavdt_scb_chk_snd_pkt(tAVDT_SCB*p_scb,tAVDT_SCB_EVT*p_data)avdt_ad_write_req(AVDT_CHAN_MEDIA,p_scb->p_ccb,p_scb,p_pkt);L2CA_DataWrite(avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][tcid].lcid,p_buf);
3 L2CAP to HCI layer
12345678910111213141516171819202122
bluedroid/stack/l2cap/l2c_api.c1633UINT8L2CA_DataWrite(UINT16cid,BT_HDR*p_data)1636returnl2c_data_write(cid,p_data,L2CAP_FLUSHABLE_CH_BASED);p_ccb=l2cu_find_ccb_by_cid(NULL,cid);l2c_csm_execute(p_ccb,L2CEVT_L2CA_DATA_WRITE,p_data);935staticvoidl2c_csm_open(tL2C_CCB*p_ccb,UINT16event,void*p_data)//Just consider channel connected state1050caseL2CEVT_L2CA_DATA_WRITE:/* Upper layer data to send */1051l2c_enqueue_peer_data(p_ccb,(BT_HDR*)p_data);1052l2c_link_check_send_pkts(p_ccb->p_lcb,NULL,NULL);1053break;l2c_link_check_send_pkts(p_lcb,NULL,NULL);l2c_link_send_to_lower(p_lcb,p_buf);1341#ifBLE_INCLUDED==TRUE1342if(p_lcb->is_ble_link)1344L2C_LINK_SEND_BLE_ACL_DATA(p_buf);1346else1349L2C_LINK_SEND_ACL_DATA(p_buf);bte_main_hci_send((BT_HDR*)(p),BT_EVT_TO_LM_HCI_ACL);bt_hc_if->transmit_buf((TRANSAC)p_msg,\(char*)(p_msg+1),p_msg->len);bluedroid/hci/src/bt_hci_bdroid.c:249staticinttransmit_buf(TRANSACtransac,char*p_buf,intlen)utils_enqueue(&tx_q,(void*)transac);bthc_signal_event(HC_EVENT_TX);
bluedroid/hci/src/bt_hci_bdroid.c339staticvoid*bt_hc_worker_thread(void*arg)if(events&HC_EVENT_RX)p_hci_if->rcv();uint16_thci_h4_receive_msg(void)//Construct HCI EVENT/ACL packets and send them to stack957if(p_cb->p_rcv_msg->event!=MSG_HC_TO_STACK_HCI_ACL)958btsnoop_capture(p_cb->p_rcv_msg,TRUE);//dump to HCI trace file/socket.960if(p_cb->p_rcv_msg->event==MSG_HC_TO_STACK_HCI_EVT)965bt_hc_cbacks->data_ind((TRANSAC)p_cb->p_rcv_msg,(char*)(p_cb->p_rcv_msg+1),p_cb->p_rcv_msg->len+BT_HC_HDR_SIZE);bluedroid/main/bte_main.c:504staticintdata_ind(TRANSACtransac,char*p_buf,intlen)GKI_send_msg(BTU_TASK,BTU_HCI_RCV_MBOX,transac);//handle in btu_task.