setting 界面开始搜索的时候,通常也会同时进行le scan,这一点在inquiry流程之命令下发中已经讲述。此篇文章主要是分析一下对于controller 搜索到的广播包的处理。这里以Android O的bluedroid的代码作为分析对象。
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_t)(p_msg->event & BT_SUB_EVT_MASK), p_msg); osi_free(p_msg); break; case BT_EVT_TO_BTU_HCI_CMD: btu_hcif_send_cmd((uint8_t)(p_msg->event & BT_SUB_EVT_MASK), p_msg); break; default: osi_free(p_msg); break; } }
上面可以看出 btu_hci_msg_process 的所有的处理对象。hci event 的处理函数 是btu_hcif_process_event((uint8_t)(p_msg->event & BT_SUB_EVT_MASK), p_msg);
void btu_hcif_process_event(UNUSED_ATTR uint8_t controller_id, BT_HDR* p_msg) { uint8_t* p = (uint8_t*)(p_msg + 1) + p_msg->offset; uint8_t hci_evt_code, hci_evt_len; uint8_t ble_sub_code; STREAM_TO_UINT8(hci_evt_code, p); STREAM_TO_UINT8(hci_evt_len, p); switch (hci_evt_code) { case HCI_INQUIRY_COMP_EVT: btu_hcif_inquiry_comp_evt(p); break; case HCI_INQUIRY_RESULT_EVT: btu_hcif_inquiry_result_evt(p); break; case HCI_INQUIRY_RSSI_RESULT_EVT: btu_hcif_inquiry_rssi_result_evt(p); break; ... case HCI_BLE_EVENT: { //le 相关的event STREAM_TO_UINT8(ble_sub_code, p); uint8_t ble_evt_len = hci_evt_len - 1; switch (ble_sub_code) { //判断子event case HCI_BLE_ADV_PKT_RPT_EVT: /* result of inquiry */ HCI_TRACE_EVENT("HCI_BLE_ADV_PKT_RPT_EVT"); btm_ble_process_adv_pkt(ble_evt_len, p);//处理广播包 break; case HCI_BLE_CONN_COMPLETE_EVT: btu_ble_ll_conn_complete_evt(p, hci_evt_len); break; case HCI_BLE_LL_CONN_PARAM_UPD_EVT: btu_ble_ll_conn_param_upd_evt(p, hci_evt_len); break; ...
从上面可以看出 btu_hcif_process_event可以处理的event 的类型,并且可以看出处理广播包的函数 是 btm_ble_process_adv_pkt(ble_evt_len, p);从函数名称可以看出此时函数已经进入到btm 模块,其实现在btm_ble_gap.cc
/** * This function is called when advertising report event is received. It updates * the inquiry database. If the inquiry database is full, the oldest entry is * discarded. */ void btm_ble_process_adv_pkt(uint8_t data_len, uint8_t* data) { BD_ADDR bda; uint8_t* p = data; uint8_t legacy_evt_type, addr_type, num_reports, pkt_data_len; int8_t rssi; /* Extract the number of reports in this event. */ STREAM_TO_UINT8(num_reports, p);//一个包里面可能有多个event,但是通常只有一个event while (num_reports--) { /* Extract inquiry results */ STREAM_TO_UINT8(legacy_evt_type, p);//event_type STREAM_TO_UINT8(addr_type, p);//地址类型 STREAM_TO_BDADDR(bda, p);//地址 STREAM_TO_UINT8(pkt_data_len, p);//数据长度 uint8_t* pkt_data = p; p += pkt_data_len; /* Advance to the the rssi byte */ STREAM_TO_INT8(rssi, p);//此时指针指向数据末尾的rssi btm_ble_process_adv_addr(bda, addr_type);//处理地址相关 uint16_t event_type; if (legacy_evt_type == 0x00) { // ADV_IND; event_type = 0x0013; } else if (legacy_evt_type == 0x01) { // ADV_DIRECT_IND; event_type = 0x0015; } else if (legacy_evt_type == 0x02) { // ADV_SCAN_IND; event_type = 0x0012; } else if (legacy_evt_type == 0x03) { // ADV_NONCONN_IND; event_type = 0x0010; } else if (legacy_evt_type == 0x04) { // SCAN_RSP; // We can't distinguish between "SCAN_RSP to an ADV_IND", and "SCAN_RSP to // an ADV_SCAN_IND", so always return "SCAN_RSP to an ADV_IND" event_type = 0x001B; } btm_ble_process_adv_pkt_cont( event_type, addr_type, bda, PHY_LE_1M, PHY_LE_NO_PACKET, NO_ADI_PRESENT, TX_POWER_NOT_PRESENT, rssi, 0x00 /* no periodic adv */, pkt_data_len, pkt_data);//开始处理数据包 } }