蓝牙inquiry流程之Advertising Report

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);//开始处理数据包
  }
}

猜你喜欢

转载自www.cnblogs.com/libs-liu/p/9238209.html