刷机后蓝牙广播没有名字,只显示MAC地址
文章目录
刷机后,第一次打开蓝牙,在别的手机上搜到的蓝牙显示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; }
既然这样,那就在系统初开始搜索设备的时候,设置一下蓝牙名称再开始搜索就行了。
文章作者 carter2005
上次更新 2019-01-30