蓝牙设备的发现和同步简介:
蓝牙设备在建立连接以前通过在固定的一个频段内选择跳频频率由或被查询的设备地址决定,迅速交换握手信息时间和地址,快速取得设备的时间和频率同步建立连接后,设备双方根据信道跳变序列改变频率,使跳频频率呈现随机特性。蓝牙系统定义了种工作状态下的跳频序列寻呼、寻呼响应、查询、查询响应 和信道 跳变序列, 不同状态下的跳频序列产生策略不同。
蓝牙定义了32个频点为一个频段, 划分为79个子频段, 工作的频段及跳频顺序取决于所输入的蓝牙主控设备时钟CLK 和主控设备地址的最低28比特有效位, 即BD_ADDR[0…27]或者28比特通用查询接入码(General Inquiry Access Code,GIAC).
查询/查询扫描状态:
蓝牙设备通过查询来寻找在其周围邻近的设备,查询设备每隔312.5微秒选择一个新的频率来发送查询,被查询设备每个1.28s选择一次新的监听频率。查询和被查询设备使用通用查询接人码(GIAC,General Inquiry Acess Code)LAP(Low Address Part),作为查询地址,GIAP LAP为0x9E8B33.蓝牙标准规定不允许任何蓝牙设备使用和GIAP LAP一样的地址。产生的32个查 询跳变序列(Inquiring hopping sequence) 均匀分布在79个频率信道上。
寻呼/寻呼扫描状态:
蓝牙设备通过寻呼来呼叫其它的设备加入其所在的微微网,寻呼设备每隔312.5微秒选择一个新的频率来发送寻呼,在寻呼扫描时,被寻呼设备每隔1.28s选择一个新的监听频率。寻呼和被寻呼设备使用被寻呼设备地址(BT_ADDR)的底28个比特,产生的寻呼跳变序列(paging –hopping sequence)是一个定义明确的周期序列,它的个频点均匀分布在2.4G的79个频率信道上.
连接状态:
在当前状态下,蓝牙通信设备双方每隔625微秒改变一个频率,使用主设备地址的最低28位 有效位, 产生的信道跳变序列(Channel hopping sequence)周期非常长,而且79跳变序
列在任何的一小段时间内都是接近均匀分布的。
蓝牙状态转换图:
Page scan:这个子状态是和page对应的,它就是等待被page的slave所处的状态,换句话说,若想被page到,我们就要处于page scan的状态。
inquiry:这就是我们通常所说的扫描状态,这个状态的设备就是去扫描周围的设备。
inquiry scan:这就是我们通常看到的可被发现的设备。体现在上层就是我们在android系统中点击设备可被周围什么发现,那设备就处于这样的状态。
slave response:这个就是在page的过程中,slave收到了master的page msg,它会回应对应的pageresponse msg,同时自己就进入到了slave response的状态。
master response:master收到slaveresponse的msg后,他就会进入到master response的状态,同时他会发送一个FHS的packet。
各种状态间的转换:
standby->inquiry:当一个设备需要去扫描周围是否有别的设备的时候,就会从standby转变到inquiry的状态。到了这个状态之后,他就会重复地发送inquiry的msg,inquiry msg并没有标明任何和source相关的信息,但是它可能包含哪一类的设备应当响应这个msg。处于inquiry scan的设备,就可以响应inquiry的msg了,但是spec中说并不是所有处于inquiryc scan的设备都必须响应inquiry的msg。所以,还是有一定的自主权的,哈哈~~。
在inquiry状态的设备会收到被搜索到的设备发回的response,需要注意的是inquiry状态的设备并不需要对这个response做出任何形式的回应。因为一段时间内进行inquiry的频点范围是有限的,若想搜索到所有频点的设备,需要保证inquiry的最短时间是10.24s。这一点是尤为重要的,这也是为什么我们通常看到一些设备如Android他的搜索时间都是设为10.24s,就是这个原因。
inquiry->connection:在搜索到一个设备之后,就可以根据搜索到的信息进行连接该设备,从而进入到connection的状态。
inquiry->standby:若是不进行连接或者没有搜索到任何设备,在一定时间之后,仍然会回复到standby的状体。
connection->inquiry:和standy->inquiry比较类似,唯一的差别在于standby到inquiry可以集中全部的能力去进行inquiry,而connection到inquiry则因为有别的事情需要做,需要做一些善后的工作,比如把ACL link置到sniff状态,若是有SCO或者ESCO,则会比inquiry的优先级更高,先保证SCO或者ESCO的传输,在空隙时间才能进行inquiry。
standby->inquiry scan:若是一个设备想被发现,则会进入到inquiryscan的状态。在此状态若是收到inquiry的msg就可以进行回应了。
inquiry scan->inquiry response:在收到inquiry的msg后,就可以回应对应的inquiry的msg,从而进入到inquiryresponse的状态。回应的inquiry response有两种情况,一种就是很单纯地只回应对应的FHS的packet,另外一种就是有EIR(Entended Inquiry Result) data。是否有EIR data是FHS中的一个标志位来决定的。
inquiry response->inquiry scan: 这有两种情况,一种是我们下面要去和master建立连接从而进入到connection状态,必须要经过inquiry scan状态后才行,而不是直接就进入到conneciton状态。另外一种就是回到原来的standby状态,同样的,我们仍然要经过这个inquiry scan的状态。
inquiry scan->connection:这个和inquiry到connection状态是类似,就不多说了。
connection->inquiry scan:这个状态的变化和standy->inquiryscan是类似的,也不多说了。
standy->page scan:若是一个设备想被page到则需要进入到pagescan状态。
page scan->slave response:在收到page的msg后,page scan的设备就会发送对应的responsemsg,然后进入到slave response的状态。
slave response->connection:在第一次回应response之后,maste和slave的交互并没有完全结束。他们仍然还有别的msg的交互,在master收到slave的response之后,他会发送对应的FHS packet过来,这个时候slave response状态的设备需要再次回复一个response。在master收到这第二个response的时候,他会发送一个poll的packet下来,从这个时间点开始,slave正式进入到conneciton的状态(step5)。具体可以参见下面图
slave response->page scan:这个就是上面这个过程出问题了,就会回到pagescan的状态。
page scan->connection:需要注意这不是一个正常的流程,它发生在connection->pagescan后page失败,他就会返回到connection状态,而不是从standy->page scan->connection。和page scan到standy类似。
page scan->standby:page失败,返回之前的standby状态。
connection->page scan:和standy到page scan类似。
standy/connection->page:若想page到一个设备,就需要进入到page的状态。
page->standy/connection:同样的page失败回复对应的初始状态。
page->master response:在收到slave的response之后,就回应对应的FHSpacket,从而进入到master response的状态。
master response->connection:和slaveresponse到connection是同步类似的,不详细解释。
master response->page: 同样的是在上面出问题了,就回到page的状态了。
connection->standby:这个就是断开连接了,建立连接要走很多中间步骤,断开连接就没有这么麻烦了,直接搞定。当然理论上还是需要通过reset或者detach命令进行的。