被动扫描〔PassiveScanning〕:
只接收帧,不发送帧。
主动扫描〔ActiveScanning〕:
监听广播帧,根据广播帧格式,回复相应帧。
ADV_IND/ADV_SCAN_IND->SCAN_REQ
ADV_DIRECT_INDPDU/ADV_NONCONN_IND不回复SCAN_REQ
扫描需进行退避操作。
具体看文档吧,就不贴进来了。
2、initiating
initiating没有channelindex的限制。
当收到一个在过滤白名单内的ADV_IND或ADV_DIRECT_IND,发起者将会发送一个CONNECT_REQ给广播方。
发送完CONNECT_REQ后退出发起状态,进入连接状态。
四、连接状态简述:
当发起者发送CONNECT_PDU或者广播方收到CONNECT_REQ,则认为连接被创建,但此时并非认为已经建立连接。
只有当正式开始数据通信后,才认为连接已经被建立。
连接建立后,连接中有两个角色:
Master和Slave。
Master主控connectionevent的时序。
每次connectionevent便是Master和Slave的一次同步结点。
1、连接事件〔ConnectionEvents〕
一次连接时间,使用同一个channelindex。
每次连接至少进行一次数据传输。
Slave端在接收到来自Master的数据帧后,无论CRC是否正确,均需要回复数据,除非多次连续CRC不正确。
Master也是不管Slave发过来的帧是否正确,均需回复数据,没有除非。
无论CRC是否正确,我们都认为Header是对的。
Master收不到来自Slave的数据,则关闭connectionevent。
Master和Slave都能关闭此次connection。
连接事件持续时间长度由connInterval和connSlaveLatency决定。
每次连接事件的起始点称作anchorpoint。
在anchorpoint,Master开始发送数据,Slave开始接收数据。
connInterval便是本次连接的持续时间。
Master必须确保本次连接时间在下次anchorpoint之前间隔T_IFS的时间关闭。
connInterval长度必须是的倍数,长度在不等。
connInterval由发起者通过CONNNECT_REQ传送给广播方。
connSlaveLatency是Slave端允许的监听延时时间,其长度范围如下:
0~((connSupervisionTimeout/connInterval)-1)且必须小于500。
也就是说,假设connSlaveLatency=0,则Slave需要在每个anchorpoint时刻监听。
没收到设置connSlaveLatency的帧时,亦如是。
Master和Slave均有一个16bit的计数器connEventCounter每有一次connectionevent,计数器就加一,假设溢出则循环。
它是用于LinkLayer作同步时用。
Slave在等待connSlaveLatency时,该计数器亦计数。
2、连接超时〔SupervisionTimeout〕
蓝牙系统为了检测连接丧失,便设置了一个SupervisionTimeout计数器TLLconnSupervision。
每次接收到数据帧,则计数器清零。
SupervisionTime超过以下几个范围则认为超时:
·大于6*connInterval
·大于connSupervisionTimeout
connSupervisionTimeout为10ms的倍数,范围是100ms~32s,并且小于(1+connSlaveLatency)*connInterval。
Timeout以后,设备停止发送,进入Standby状态,并且上报中断。
3、发送窗〔TransmitWindow〕
TransmitWindow的信息包含在CONNECT_REQ中,传送给发起者。
发送窗起始是在收到CONNECT_REQ之后transmitWindowOffset5ms,
transmitWindowSize定义发送窗的宽度。
transmitWindowOffset范围的倍数,0ms~connInterval。
transmitWindowSize范围的倍数,1.25ms~10ms|connInterval-1.25ms。
4、主设备〔MasterRole〕
建立连接后,发起的一方成为Master。
连接状态建立以后,Master重新设置TLLconnSupervision,LinkLayer确认连接已经建立。
随后Master在transmitwindow时间内开始发送第一个数据帧,Master的第一帧长度可以超过transmitwindow。
Master决定第一个anchorpoint,
下一个anchorpoint=connInterval+firstanchorpoint。
以下是一个例子:
5、从设备〔SlaveRole〕
建立连接后,广播的一方成为Slave。
Slave一方也相同,重新设置TLLconnSupervision,LinkLayer确认连接已经建立。
连接建立后的第一帧,无论CRC是否收对,都把它作为第一次连接事件的anchorevent。
假设第一个transmitwindow没有收到数据帧,则准备在下一个transmitwindow下接收数据,而此时事件同步计数器connEventCount亦加一。
6、关闭连接事件〔ClosingConnectionEvents〕
Header中的MD位标识是否该次事件之后还有数据发送。
假设MD置位,则Master接着发,Slave接着收。
任何一方收不到对方的帧了,均关闭连接事件。
连续两次收到数据CRC不对,也关闭连接事件。
总结如下:
7、发送窗拓宽〔WindowWidening〕
由于发送端接收端都存在晶振频偏,所以可能会导致Slave端anchorpoint不同步,因此Slave每次接收完一个数据帧,均需同步一次anchorpoint。
接收端需要根据发送端的频偏MasterSCA和接收端频偏SlaveSCA来计算接收端的接收窗拓宽参数,以保证数据成功接收。
计算方式如下:
其值应小于((connInterval/2)-T_IFSus)。
假设到达这个值,则认为连接丧失。
8、信道列表选择〔DataChannelIndexSelection〕
Master端需要给此次连接的信道分类:
使用信道和不使用信道。
使用信道最少为两个。
信道分类由HOST产生。
而Slave的ChannelMap通过CONNECT_REQ帧接收到本地。
连续的connectionevent每次需要获取两个参数unmappedChannel和lastUnmappedChannel。
前者是此次连接没有使用过的信道列表,后者是前一次连接未用过的信道编号。
未用信道编号计算方法如下:
unmappedChannel=(lastUnmappedChannel+hopIncrement)mod37
假设unmappedChannel为usedChannel的话,则此次的ChannelIndex则根据这个unmappedChannel得到该次connection所使用的Channel。
假设unmappedChannel为unusedChannel,则根据下面公式计算得到一个remappingIndex。
remappingIndex=unmappedChannelmodnumUsedChannels
总结如下列图:
9、确认机制和数据流控制〔AcknowledgementandFlowControl〕
数据确实认依靠transmitSeqNum〔SN〕和nextExpectedSeqNum〔NESN〕来控制。
NESN用于确认前一帧是否接收正确,是否需要重发。
刚刚进入连接状态,SN和NESN均需设置成0。
控制方式如下列图:
NESN在一种情况下不会被更新,就是接收BUFFER不够的情况。
这会使发送端重传该帧,如此实现数据流控制。
五、LinkLayer控制描述
LLCP〔LinkLayerControlProtocol〕是用来控制两个LinkLayer之间的控制和协商的。
其中包括连接控制,加密控制等等。
1、LinkLayer连接更新和ChannelMap更新
每次进入连接状态后,设备均需更新connInterval,connSlaveLatency和connSupervisionTimeout。
Master通过发送LL_CONNECTION_UPDATE_REQ帧来实现参数更新,Slave不能发送这种格式的帧,它通过使用L2CAP信道回复更新确认来确认参数更新。
参数更新之前使用老的参数,更新之后使用新参数。
Slave端收到LL_CONNECTION_UPDATE_REQ之后,假设
connEventCountmod65535小于32767,并且不等于本地的connEventCount,此时它需监听所有的ConnectionEvent,直到确认Master收到自己的REQACK。
Slave在确认两边connEventCount相等之前的ConnectionEvent均需要监听。
假设connEventCountmod65535大于32767,则Slave认为与Master丧失连接,回到Standby状态,并上报主机。
Master这边,需要在第一个TransmitWindow内发送数据,它发送的这帧数据作为此次Connection的anchorpoint。
Master在这个anchorpoint以后更新它的connInterval,并清零TLLconnSupervision计数。
假设使用自动发送LL_CONNECTION_UPDATE_REQ,则Timeout参数不跟新,与前次LL_CONNECTION_UPDATE_REQ或者CONNECT_REQ设置时相同。
其他参数亦如是。
自动更新机制用于Master由于其他需求,需要更改anchorpoint时间。
ChannelMap的更新由LL_CHANNEL_MAP_REQ完成,
2、加密
加密参数设置通过LL_ENC_REQ和LL_ENC_RSP
开始加密:
LL_START_ENC_REQ和LL_START_ENC_RSP
结束加密:
LL_PAUSE_ENC_REQorLL_TERMINATE_INDPDUs
EmptyPDUsorLL_PAUSE_ENC_RSPorLL_TERMINATE_IND
3、FeatureSetExchange
进入连接状态以后,蓝牙设备之间需要交换各自所支持的功能参数。
该过程通过LL_FEATURE_REQPDU和LL_FEATURE_RSPPDU交换信息。
数据帧交换时间关系如下:
具体的Feature对应位如下列图所示:
4、VersionExchange
主从之间交换设备所支持的蓝牙协议版本信息,通过LL_VERSION_IND来交换信息。
其信息包括:
VersNr:
所支持的蓝牙协议
CompId:
认证信息
SubVersNr:
Controller的实现版本号。
5、TerminationProcedure
终止通信,通过LL_TERMINATE_IND来交换信息。
IP架构
以下是几个理解上的难点:
一、关于ExchangeTable和ControlStructure
ExchangeMemory是一个动态的存储器件,其中包括了ExchangeTabel、ControlStructure、T/RxDescriptor、T/RxBuffer,它们之间的连接都是由指针完成。
关系大概如下:
首先需要将ControlStructure和TRXDescriptor在EM中配置完成后,再配置ExchangeTabel。
其可配置的空间如下列图所示:
也就是说首先需要在0x0050~0xFFFF地址内配置ControlStructure、Descriptor和DataBuffer,然后在0x0000~0x001F内配置C