一、inquiry 和inquiry scan
在讲搜索过程之前,需要了解两个状态,分别是inquiry和inquiry scan,主动发起搜索的一方是inquiry,能够被其他蓝牙设备搜索到的设备处于inquiry scan状态。
(在没有建立连接之前,是没有master和slave的概念的,但是为了好描述,在这篇文档内被搜索的设备被称为slave,主动发起搜索的设备称为master)
二、inquiry scan涉及到的HCI指令
1.hci_write_inquiry_scan_activity
指令包含两个参数:
inquiry_scan_interval:两次连续inquiry_scan_window之间的间隔,范围是11.25ms~2560ms
intuiry_scan_window:处于inquiry scan状态的时间,范围是10.625ms~2560ms
intuiry_scan_window必须是小于等于intuiry_scan_interval。
这两个参数主要影响的是被搜索设备能够被其他蓝牙设备搜索到的难易程度,window越大,interval越小,就越容易被其他设备搜索到;反之,如果window越小,interval越大,就越难被搜索到。
当然,host也可以不设置这两个参数,那么就是默认值,interval:2.56s,window:11.25ms
2.hci_write_scan_enable
host通过这个指令来让controller进入inquiry scan状态
3.hci_write_extended_inquiry_response
这个指令是可选的,host不下发这个指令也没关系。
如果slave的host不去下发这个指令,那么master搜索到后就只能拿到slave的设备地址和设备类型,设备名字是拿不到的,只能后续通过HCI_Remote_Name_Request指令来获取slave的名字。
当然在extended_iqnuiry_response里不仅仅可以写设备名字,也可以一并把slave支持的service也写进去,比如音频相关的audio source,Hands-Free audio gateway等等
三、inquiry涉及到的HCI指令
1.HCI_inquiry
LAP:不需要太关注,一般是0x9e8b33(GIAC)
inquiry_length:搜索多长时间
num_response:可以搜索多少个设备,范围0~255,如果是0,就是没有限制,搜索多少个就上报给host多少个。
2.HCI_Inquiry_Cancel
host要是想提前结束搜索,可以通过发inquiry_cancel指令来停止搜索
3.HCI_Write_Inquiry_Mode
inquiry mode不同,对应不同的inquiry result event,一般的host都是设置的0x02
三、空中时序
设备进入inquiry状态后,会每间隔1个slot连续发2个ID包,而slave就在inquiry_scan_window内去监听ID包(这就解释了为什么被搜索的设备叫做inquiry scan),一旦slave扫描到了ID包,slave就会回一个FHS包,里面包含着slave的时钟信息,它的设备类型等。
因为master在1个slot内是发的两个ID包,那么对于slave来说就有两种情况,一种是收到了第一个ID包,另一种是收到了第二个ID包。两种情况对应着两种时序
收到了第一个ID包:
收到了第二个ID包:
其实不管slave收到哪个ID包,都需要在收到的ID包后1个slot发FHS包。因为在连接成功后,两个设备的通信时序都是按slot为单位来计算的。
slave的信息就包含在FHS包里。
FHS包格式:
class of device :设备类型,比如音响、耳机、鼠标等等
LAP UAP NAP三个字段组成蓝牙地址
EIR:如果host下发了hci_write_extended_inquiry_response指令,这个字段就会设置为1,表示在FHS包后的2个slot(1250us),slave还有一个叫Extended_inquiry_response_packet这样的包要发,设备名字,service uuid等信息就包含在这里面。
根据slave的FHS包里的EIR字段是否是1,master会通过不同的event来上报给master的host。
EIR为0:
或者
区别是是否带有slave的信号强度(RSSI)
EIR为1: