2019-03-12

蓝牙配对流程梳理
http://www.cnblogs.com/libs-liu/p/10175949.html

蓝牙扫描
https://blog.csdn.net/xubin341719/article/details/38584469

3.static int start_discovery流程

static int start_discovery(void) {
  /* sanity check */
  if (!interface_ready()) return BT_STATUS_NOT_READY;

  return btif_dm_start_discovery();
}

返回btif_dm_start_discovery(),关注该函数实现

bt_status_t btif_dm_start_discovery(void) {
  tBTA_DM_INQ inq_params;
  tBTA_SERVICE_MASK services = 0;

  BTIF_TRACE_EVENT("%s", __func__);

  /* Cleanup anything remaining on index 0 */
  do_in_bta_thread(
      FROM_HERE,
      base::Bind(&BTM_BleAdvFilterParamSetup, BTM_BLE_SCAN_COND_DELETE, 0,
                 nullptr, base::Bind(&bte_scan_filt_param_cfg_evt, 0)));

  auto adv_filt_param = std::make_unique();
  /* Add an allow-all filter on index 0*/
  adv_filt_param->dely_mode = IMMEDIATE_DELY_MODE;
  adv_filt_param->feat_seln = ALLOW_ALL_FILTER;
  adv_filt_param->filt_logic_type = BTA_DM_BLE_PF_FILT_LOGIC_OR;
  adv_filt_param->list_logic_type = BTA_DM_BLE_PF_LIST_LOGIC_OR;
  adv_filt_param->rssi_low_thres = LOWEST_RSSI_VALUE;
  adv_filt_param->rssi_high_thres = LOWEST_RSSI_VALUE;
  do_in_bta_thread(
      FROM_HERE, base::Bind(&BTM_BleAdvFilterParamSetup, BTM_BLE_SCAN_COND_ADD,
                            0, base::Passed(&adv_filt_param),
                            base::Bind(&bte_scan_filt_param_cfg_evt, 0)));

  /* TODO: Do we need to handle multiple inquiries at the same time? */

  /* Set inquiry params and call API */
  inq_params.mode = BTA_DM_GENERAL_INQUIRY | BTA_BLE_GENERAL_INQUIRY;
  inq_params.duration = BTIF_DM_DEFAULT_INQ_MAX_DURATION;

  inq_params.max_resps = BTIF_DM_DEFAULT_INQ_MAX_RESULTS;
  inq_params.report_dup = true;

  inq_params.filter_type = BTA_DM_INQ_CLR;
  /* TODO: Filter device by BDA needs to be implemented here */

  /* Will be enabled to true once inquiry busy level has been received */
  btif_dm_inquiry_in_progress = false;
  /* find nearby devices */
  BTA_DmSearch(&inq_params, services, bte_search_devices_evt);

  return BT_STATUS_SUCCESS;
}

1.do_in_bta_thread:Post a closure to be ran in the bta thread
2.BTA_DmSearch
搜索蓝牙设备,执行查询并获取设备的远程名称.

void BTA_DmSearch(tBTA_DM_INQ* p_dm_inq, tBTA_SERVICE_MASK services,
                  tBTA_DM_SEARCH_CBACK* p_cback) {
  tBTA_DM_API_SEARCH* p_msg =
      (tBTA_DM_API_SEARCH*)osi_calloc(sizeof(tBTA_DM_API_SEARCH));

  p_msg->hdr.event = BTA_DM_API_SEARCH_EVT;
  memcpy(&p_msg->inq_params, p_dm_inq, sizeof(tBTA_DM_INQ));
  p_msg->services = services;
  p_msg->p_cback = p_cback;//将函数指针赋值
  p_msg->rs_res = BTA_DM_RS_NONE;

  bta_sys_sendmsg(p_msg);//将该结构体变量发送
}

bta_sys_sendmsg

void bta_sys_sendmsg(void* p_msg) {
  base::MessageLoop* bta_message_loop = get_message_loop();

  if (!bta_message_loop || !bta_message_loop->task_runner().get()) {
    APPL_TRACE_ERROR("%s: MessageLooper not initialized", __func__);
    return;
  }

  bta_message_loop->task_runner()->PostTask(
      FROM_HERE, base::Bind(&bta_sys_event, static_cast(p_msg)));
}

回到BTA_DmSearch,传入的函数指针是bte_search_devices_evt,关注一下这个函数
关于这个函数的注释:
从BTE切换到BTIF,进行DM搜索

/*******************************************************************************
 *
 * Function         bte_search_devices_evt
 *
 * Description      Switches context from BTE to BTIF for DM search events
 *
 * Returns          void
 *
 ******************************************************************************/
static void bte_search_devices_evt(tBTA_DM_SEARCH_EVT event,
                                   tBTA_DM_SEARCH* p_data) {
  uint16_t param_len = 0;

  if (p_data) param_len += sizeof(tBTA_DM_SEARCH);
  /* Allocate buffer to hold the pointers (deep copy). The pointers will point
   * to the end of the tBTA_DM_SEARCH */
  switch (event) {
    case BTA_DM_INQ_RES_EVT: {
      if (p_data->inq_res.p_eir) param_len += p_data->inq_res.eir_len;
    } break;

    case BTA_DM_DISC_RES_EVT: {
      if (p_data->disc_res.raw_data_size && p_data->disc_res.p_raw_data)
        param_len += p_data->disc_res.raw_data_size;
    } break;
  }
  BTIF_TRACE_DEBUG("%s event=%s param_len=%d", __func__,
                   dump_dm_search_event(event), param_len);

  /* if remote name is available in EIR, set teh flag so that stack doesnt
   * trigger RNR */
  if (event == BTA_DM_INQ_RES_EVT)
    p_data->inq_res.remt_name_not_required =
        check_eir_remote_name(p_data, NULL, NULL);

  btif_transfer_context(
      btif_dm_search_devices_evt, (uint16_t)event, (char*)p_data, param_len,
      (param_len > sizeof(tBTA_DM_SEARCH)) ? search_devices_copy_cb : NULL);
}

关注btif_transfer_context功能

/*******************************************************************************
 *
 * Function         btif_transfer_context
 *
 * Description      This function switches context to btif task
 *
 *                  p_cback   : callback used to process message in btif context
 *                  event     : event id of message
 *                  p_params  : parameter area passed to callback (copied)
 *                  param_len : length of parameter area
 *                  p_copy_cback : If set this function will be invoked for deep
 *                                 copy
 *
 * Returns          void
 *
 ******************************************************************************/

bt_status_t btif_transfer_context(tBTIF_CBACK* p_cback, uint16_t event,
                                  char* p_params, int param_len,
                                  tBTIF_COPY_CBACK* p_copy_cback) {
  tBTIF_CONTEXT_SWITCH_CBACK* p_msg = (tBTIF_CONTEXT_SWITCH_CBACK*)osi_malloc(
      sizeof(tBTIF_CONTEXT_SWITCH_CBACK) + param_len);

  BTIF_TRACE_VERBOSE("btif_transfer_context event %d, len %d", event,
                     param_len);

  /* allocate and send message that will be executed in btif context */
  p_msg->hdr.event = BT_EVT_CONTEXT_SWITCH_EVT; /* internal event */
  p_msg->p_cb = p_cback;

  p_msg->event = event; /* callback event */

  /* check if caller has provided a copy callback to do the deep copy */
  if (p_copy_cback) {
    p_copy_cback(event, p_msg->p_param, p_params);
  } else if (p_params) {
    memcpy(p_msg->p_param, p_params, param_len); /* callback parameter data */
  }

  btif_sendmsg(p_msg);

  return BT_STATUS_SUCCESS;
}

该函数将传进来的函数指针赋值给p_msg->p_cb = p_cback;
并通过btif_sendmsg(p_msg),将该结构体变量发送

所以可以关注该函数传进来的函数指针内的内容

btif_transfer_context(
      btif_dm_search_devices_evt, (uint16_t)event, (char*)p_data, param_len,
      (param_len > sizeof(tBTA_DM_SEARCH)) ? search_devices_copy_cb : NULL);

其中btif_dm_search_devices_evt函数
在btif目录中执行搜索设备回调事件

/******************************************************************************
 *
 * Function         btif_dm_search_devices_evt
 *
 * Description      Executes search devices callback events in btif context
 *
 * Returns          void
 *
 *****************************************************************************/
static void btif_dm_search_devices_evt(uint16_t event, char* p_param) {
  tBTA_DM_SEARCH* p_search_data;
  BTIF_TRACE_EVENT("%s event=%s", __func__, dump_dm_search_event(event));

  switch (event) {
    case BTA_DM_DISC_RES_EVT: {
      p_search_data = (tBTA_DM_SEARCH*)p_param;
      /* Remote name update */
      if (strlen((const char*)p_search_data->disc_res.bd_name)) {
        bt_property_t properties[1];
        bt_status_t status;

        properties[0].type = BT_PROPERTY_BDNAME;
        properties[0].val = p_search_data->disc_res.bd_name;
        properties[0].len = strlen((char*)p_search_data->disc_res.bd_name);
        RawAddress& bdaddr = p_search_data->disc_res.bd_addr;

        status =
            btif_storage_set_remote_device_property(&bdaddr, &properties[0]);
        ASSERTC(status == BT_STATUS_SUCCESS,
                "failed to save remote device property", status);
        HAL_CBACK(bt_hal_cbacks, remote_device_properties_cb, status, &bdaddr,
                  1, properties);
      }
      /* TODO: Services? */
    } break;

    case BTA_DM_INQ_RES_EVT: {
      /* inquiry result */
      bt_bdname_t bdname;
      uint8_t remote_name_len;
      tBTA_SERVICE_MASK services = 0;

      p_search_data = (tBTA_DM_SEARCH*)p_param;
      RawAddress& bdaddr = p_search_data->inq_res.bd_addr;

      BTIF_TRACE_DEBUG("%s() %s device_type = 0x%x\n", __func__,
                       bdaddr.ToString().c_str(),
                       p_search_data->inq_res.device_type);
      bdname.name[0] = 0;

      if (!check_eir_remote_name(p_search_data, bdname.name, &remote_name_len))
        check_cached_remote_name(p_search_data, bdname.name, &remote_name_len);

      /* Check EIR for remote name and services */
      if (p_search_data->inq_res.p_eir) {
        BTA_GetEirService(p_search_data->inq_res.p_eir,
                          p_search_data->inq_res.eir_len, &services);
        BTIF_TRACE_DEBUG("%s()EIR BTA services = %08X", __func__,
                         (uint32_t)services);
        /* TODO:  Get the service list and check to see which uuids we got and
         * send it back to the client. */
      }

      {
        bt_property_t properties[5];
        bt_device_type_t dev_type;
        uint32_t num_properties = 0;
        bt_status_t status;
        int addr_type = 0;

        memset(properties, 0, sizeof(properties));
        /* RawAddress */
        BTIF_STORAGE_FILL_PROPERTY(&properties[num_properties],
                                   BT_PROPERTY_BDADDR, sizeof(bdaddr), &bdaddr);
        num_properties++;
        /* BD_NAME */
        /* Don't send BDNAME if it is empty */
        if (bdname.name[0]) {
          BTIF_STORAGE_FILL_PROPERTY(&properties[num_properties],
                                     BT_PROPERTY_BDNAME,
                                     strlen((char*)bdname.name), &bdname);
          num_properties++;
        }

        /* DEV_CLASS */
        uint32_t cod = devclass2uint(p_search_data->inq_res.dev_class);
        BTIF_TRACE_DEBUG("%s cod is 0x%06x", __func__, cod);
        if (cod != 0) {
          BTIF_STORAGE_FILL_PROPERTY(&properties[num_properties],
                                     BT_PROPERTY_CLASS_OF_DEVICE, sizeof(cod),
                                     &cod);
          num_properties++;
        }

        /* DEV_TYPE */
        /* FixMe: Assumption is that bluetooth.h and BTE enums match */

        /* Verify if the device is dual mode in NVRAM */
        int stored_device_type = 0;
        if (btif_get_device_type(bdaddr, &stored_device_type) &&
            ((stored_device_type != BT_DEVICE_TYPE_BREDR &&
              p_search_data->inq_res.device_type == BT_DEVICE_TYPE_BREDR) ||
             (stored_device_type != BT_DEVICE_TYPE_BLE &&
              p_search_data->inq_res.device_type == BT_DEVICE_TYPE_BLE))) {
          dev_type = (bt_device_type_t)BT_DEVICE_TYPE_DUMO;
        } else {
          dev_type = (bt_device_type_t)p_search_data->inq_res.device_type;
        }

        if (p_search_data->inq_res.device_type == BT_DEVICE_TYPE_BLE)
          addr_type = p_search_data->inq_res.ble_addr_type;
        BTIF_STORAGE_FILL_PROPERTY(&properties[num_properties],
                                   BT_PROPERTY_TYPE_OF_DEVICE, sizeof(dev_type),
                                   &dev_type);
        num_properties++;
        /* RSSI */
        BTIF_STORAGE_FILL_PROPERTY(&properties[num_properties],
                                   BT_PROPERTY_REMOTE_RSSI, sizeof(int8_t),
                                   &(p_search_data->inq_res.rssi));
        num_properties++;

        status =
            btif_storage_add_remote_device(&bdaddr, num_properties, properties);
        ASSERTC(status == BT_STATUS_SUCCESS,
                "failed to save remote device (inquiry)", status);
        status = btif_storage_set_remote_addr_type(&bdaddr, addr_type);
        ASSERTC(status == BT_STATUS_SUCCESS,
                "failed to save remote addr type (inquiry)", status);
        /* Callback to notify upper layer of device */
        HAL_CBACK(bt_hal_cbacks, device_found_cb, num_properties, properties);
      }
    } break;

    case BTA_DM_INQ_CMPL_EVT: {
      do_in_bta_thread(
          FROM_HERE,
          base::Bind(&BTM_BleAdvFilterParamSetup, BTM_BLE_SCAN_COND_DELETE, 0,
                     nullptr, base::Bind(&bte_scan_filt_param_cfg_evt, 0)));
    } break;
    case BTA_DM_DISC_CMPL_EVT: {
      HAL_CBACK(bt_hal_cbacks, discovery_state_changed_cb,
                BT_DISCOVERY_STOPPED);
    } break;
    case BTA_DM_SEARCH_CANCEL_CMPL_EVT: {
      /* if inquiry is not in progress and we get a cancel event, then
       * it means we are done with inquiry, but remote_name fetches are in
       * progress
       *
       * if inquiry  is in progress, then we don't want to act on this
       * cancel_cmpl_evt
       * but instead wait for the cancel_cmpl_evt via the Busy Level
       *
       */
      if (!btif_dm_inquiry_in_progress) {
        btgatt_filt_param_setup_t adv_filt_param;
        memset(&adv_filt_param, 0, sizeof(btgatt_filt_param_setup_t));
        do_in_bta_thread(
            FROM_HERE,
            base::Bind(&BTM_BleAdvFilterParamSetup, BTM_BLE_SCAN_COND_DELETE, 0,
                       nullptr, base::Bind(&bte_scan_filt_param_cfg_evt, 0)));
        HAL_CBACK(bt_hal_cbacks, discovery_state_changed_cb,
                  BT_DISCOVERY_STOPPED);
      }
    } break;
  }
}

找到回调事件的宏列表

/* Search callback events */
#define BTA_DM_INQ_RES_EVT 0  /* Inquiry result for a peer device. */
#define BTA_DM_INQ_CMPL_EVT 1 /* Inquiry complete. */
#define BTA_DM_DISC_RES_EVT 2 /* Discovery result for a peer device. */
#define BTA_DM_DISC_BLE_RES_EVT \
  3 /* Discovery result for BLE GATT based servoce on a peer device. */
#define BTA_DM_DISC_CMPL_EVT 4          /* Discovery complete. */
#define BTA_DM_DI_DISC_CMPL_EVT 5       /* Discovery complete. */
#define BTA_DM_SEARCH_CANCEL_CMPL_EVT 6 /* Search cancelled */

evet=BTA_DM_DISC_RES_EVT时

你可能感兴趣的:(2019-03-12)