刷机后,第一次打开蓝牙,在别的手机上搜到的蓝牙显示MAC地址,而非易于识别的蓝牙名称,查看蓝牙搜索的代码,发现协议栈收到BTA_DM_INQ_RES_EVT时,构造的消息内只存在mac,dev_class,dev_type。

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;

} }

 

remote name是从eir data内取得的,很显然,我们的蓝牙设备没有广播eir data。

 

static bool check_eir_remote_name(tBTA_DM_SEARCH* p_search_data, uint8_t* p_remote_name, uint8_t* p_remote_name_len) { const uint8_t* p_eir_remote_name = NULL; uint8_t remote_name_len = 0;

/* Check EIR for remote name and services */ if (p_search_data->inq_res.p_eir) { p_eir_remote_name = AdvertiseDataParser::GetFieldByType( p_search_data->inq_res.p_eir, p_search_data->inq_res.eir_len, BTM_EIR_COMPLETE_LOCAL_NAME_TYPE, &remote_name_len); if (!p_eir_remote_name) { p_eir_remote_name = AdvertiseDataParser::GetFieldByType( p_search_data->inq_res.p_eir, p_search_data->inq_res.eir_len, BTM_EIR_SHORTENED_LOCAL_NAME_TYPE, &remote_name_len); }

if (p\_eir\_remote\_name) {
  if (remote\_name\_len > BD\_NAME\_LEN) remote\_name\_len = BD\_NAME\_LEN;

  if (p\_remote\_name && p\_remote\_name\_len) {
    memcpy(p\_remote\_name, p\_eir\_remote\_name, remote\_name\_len);
    \*(p\_remote\_name + remote\_name\_len) = 0;
    \*p\_remote\_name\_len = remote\_name\_len;
  }

  return true;
}

}

return false; }

 

搜索BTM_EIR_COMPLETE_LOCAL_NAME_TYPE,发现在bta_dm_set_eir()内设置,这个函数会被bta_dm_set_dev_name()调用,继续朝上追,这个函数会在设置蓝牙名称的时候被调用。

bt_status_t btif_set_adapter_property(const bt_property_t* property) { btif_storage_req_t req; bt_status_t status = BT_STATUS_SUCCESS; int storage_req_id = BTIF_CORE_STORAGE_NOTIFY_STATUS; /* default */ char bd_name[BTM_MAX_LOC_BD_NAME_LEN + 1]; uint16_t name_len = 0;

BTIF_TRACE_EVENT(“btif_set_adapter_property type: %d, len %d, 0x%x”, property->type, property->len, property->val);

if (!btif_is_enabled()) return BT_STATUS_NOT_READY;

switch (property->type) { case BT_PROPERTY_BDNAME: { name_len = property->len > BTM_MAX_LOC_BD_NAME_LEN ? BTM_MAX_LOC_BD_NAME_LEN : property->len; memcpy(bd_name, property->val, name_len); bd_name[name_len] = ‘\0’;

  BTIF\_TRACE\_EVENT("set property name : %s", (char\*)bd\_name);

  BTA\_DmSetDeviceName((char\*)bd\_name);

  storage\_req\_id = BTIF\_CORE\_STORAGE\_ADAPTER\_WRITE;
} break;

case BT\_PROPERTY\_ADAPTER\_SCAN\_MODE: {
  bt\_scan\_mode\_t mode = \*(bt\_scan\_mode\_t\*)property->val;
  tBTA\_DM\_DISC disc\_mode;
  tBTA\_DM\_CONN conn\_mode;

  switch (mode) {
    case BT\_SCAN\_MODE\_NONE:
      disc\_mode = BTA\_DM\_NON\_DISC;
      conn\_mode = BTA\_DM\_NON\_CONN;
      break;

    case BT\_SCAN\_MODE\_CONNECTABLE:
      disc\_mode = BTA\_DM\_NON\_DISC;
      conn\_mode = BTA\_DM\_CONN;
      break;

    case BT\_SCAN\_MODE\_CONNECTABLE\_DISCOVERABLE:
      disc\_mode = BTA\_DM\_GENERAL\_DISC;
      conn\_mode = BTA\_DM\_CONN;
      break;

    default:
      BTIF\_TRACE\_ERROR("invalid scan mode (0x%x)", mode);
      return BT\_STATUS\_PARM\_INVALID;
  }

  BTIF\_TRACE\_EVENT("set property scan mode : %x", mode);

  BTA\_DmSetVisibility(disc\_mode, conn\_mode, BTA\_DM\_IGNORE, BTA\_DM\_IGNORE);

  storage\_req\_id = BTIF\_CORE\_STORAGE\_ADAPTER\_WRITE;
} break;
case BT\_PROPERTY\_ADAPTER\_DISCOVERY\_TIMEOUT: {
  /\* Nothing to do beside store the value in NV.  Java
     will change the SCAN\_MODE property after setting timeout,
     if required \*/
  storage\_req\_id = BTIF\_CORE\_STORAGE\_ADAPTER\_WRITE;
} break;
case BT\_PROPERTY\_CLASS\_OF\_DEVICE: {
  DEV\_CLASS dev\_class;
  memcpy(dev\_class, property->val, DEV\_CLASS\_LEN);

  BTIF\_TRACE\_EVENT("set property dev\_class : 0x%02x%02x%02x", dev\_class\[0\],
                   dev\_class\[1\], dev\_class\[2\]);

  BTM\_SetDeviceClass(dev\_class);
} break;
case BT\_PROPERTY\_BDADDR:
case BT\_PROPERTY\_UUIDS:
case BT\_PROPERTY\_ADAPTER\_BONDED\_DEVICES:
case BT\_PROPERTY\_REMOTE\_FRIENDLY\_NAME:
  /\* no write support through HAL, these properties are only populated from
   \* BTA events \*/
  status = BT\_STATUS\_FAIL;
  break;
default:
  BTIF\_TRACE\_ERROR("btif\_get\_adapter\_property : invalid type %d",
                   property->type);
  status = BT\_STATUS\_FAIL;
  break;

}

if (storage_req_id != BTIF_CORE_STORAGE_NO_ACTION) { /* pass on to storage for updating local database */

req.write\_req.bd\_addr = RawAddress::kEmpty;
memcpy(&(req.write\_req.prop), property, sizeof(bt\_property\_t));

return btif\_transfer\_context(execute\_storage\_request, storage\_req\_id,
                             (char\*)&req,
                             sizeof(btif\_storage\_req\_t) + property->len,
                             btif\_in\_storage\_request\_copy\_cb);

}

return status; }

既然这样,那就在系统初开始搜索设备的时候,设置一下蓝牙名称再开始搜索就行了。