最近手机的开发中遇到一个问题,具体是很难搜索到一个蓝牙鼠标。
查看该问题的AP log,发现有如下提示:
01-15 10:59:42.837 15710 15753 W bt_btm : btm_process_inq_results: BDA: 00:1f:20:ac:1b:40
01-15 10:59:42.838 15710 15753 W bt_btm : btm_process_inq_results: Dev class: 00-25-80
01-15 10:59:42.838 15710 15732 D bt_btif_config: btif_get_device_type: Device [00:1f:20:ac:1b:40] type 1
01-15 10:59:42.839 15710 15732 W BluetoothRemoteDevices: Skip class update for 00:1F:20:AC:1B:40
01-15 10:59:42.842 3393 9455 I ActivityManager: broadcast act=android.bluetooth.device.action.FOUND from pid=15710, uid=1002,parallel BR:ea627f8,u0,size=2,replaced=0,order BR:null,size=0,resultTo=null
01-15 10:59:42.845 8669 8669 V BluetoothEventManager:Settings: Received android.bluetooth.device.action.FOUND
01-15 10:59:42.845 8669 8669 D BluetoothEventManager:Settings: Device null ,Class: 1280
01-15 10:59:42.845 8669 8669 D BluetoothEventManager:Settings: found a device 00:1F:20:AC:1B:40
可以看到这个设备是被搜索到了,AMS也将搜素到的广播发出了,但是这个设备的名字是空的,只有一个MAC地址。
而设置中的代码对于不上报名字的设备,就不显示,所以这个问题的源头还是蓝牙这块,没有上报设备的名字。
进一步搜索HCI log,可以看到这个设备一直上报的是Inqury_Result_with_RSSI,可以看到Inqury_Result_with_RSSI是不包含名字的。
对于不包含名字的设备,在蓝牙inquiry结束之后,host会发Remote_Name_Request命令去获取远端的名字。
而在获取远端设备的名字的时候,出现了timeout的错误。
追踪相关的协议远吗,由于RNR是出现在inquiry结束之后,定位的代码如下所示:
**
** Function bta_dm_inq_cmpl
**
** Description Process the inquiry complete event from BTM
**
** Returns void
**
*******************************************************************************/
void bta_dm_inq_cmpl (tBTA_DM_MSG *p_data)
{
tBTA_DM_MSG * p_msg;
tBTA_DM_SEARCH data;
APPL_TRACE_DEBUG("bta_dm_inq_cmpl");
data.inq_cmpl.num_resps = p_data->inq_cmpl.num;
bta_dm_search_cb.p_search_cback(BTA_DM_INQ_CMPL_EVT, &data);
if((bta_dm_search_cb.p_btm_inq_info = BTM_InqDbFirst()) != NULL)
{
/* start name and service discovery from the first device on inquiry result */
bta_dm_search_cb.name_discover_done = FALSE;
bta_dm_search_cb.peer_name[0] = 0;
bta_dm_discover_device(bta_dm_search_cb.p_btm_inq_info->results.remote_bd_addr);
}
else
{
/* no devices, search complete */
bta_dm_search_cb.services = 0;
if ((p_msg = (tBTA_DM_MSG *) GKI_getbuf(sizeof(tBTA_DM_MSG))) != NULL)
{
p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
bta_sys_sendmsg(p_msg);
}
}
}
由于搜索到的名字是空的,所以代码走到了else分支,即BTM_InqDbFirst函数的返回值是空的,看看BTM_InqDbFirst函数;
/*******************************************************************************
**
** Function BTM_InqDbFirst
**
** Description This function looks through the inquiry database for the first
** used entry, and returns that. This is used in conjunction with
** BTM_InqDbNext by applications as a way to walk through the
** inquiry database.
**
** Returns pointer to first in-use entry, or NULL if DB is empty
**
*******************************************************************************/
tBTM_INQ_INFO *BTM_InqDbFirst (void)
{
UINT16 xx;
tINQ_DB_ENT *p_ent = btm_cb.btm_inq_vars.inq_db;
for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++)
{
if (p_ent->in_use)
return (&p_ent->inq_info);
}
/* If here, no used entry found */
return ((tBTM_INQ_INFO *)NULL);
}
最终定位到是查找时间太短造成的,将BTM_INQ_DB_SIZE的值增大解决掉这个问题。