实例分析基于RFCOMM协议大数据传输以及流控
背景
在蓝牙进行大数据传输(比如文件,OTA固件升级以及其他私有协议)一般采用两种协议,一种是经典蓝牙的RFCOMM或者基于RFCOMM的SPP协议, 一种是采用基于BLE 5.0 的extension data length特性,可以扩展MTU到512或者更大进行大数据传输。
下面我们还是以手机和耳机为例,来分析基于RFCOMM进行大数据传输的流程以及采取的流控,进行大数据传输(OTA固件,录音文件传输等等),透过手机侧的HCI LOG来进行分析RFCOMM的连接建立以及流控过程。
SDP for RFCOMM
RFCOMM是一种简单的数据传输协议,可以在RFCOMM SERVER和Client之间进行数据传输,在我们的例子中发起RFCOMM连接的一方是Client(手机),响应连接的一方是Server(耳机),下面先看看SDP for RFCOMM的HCI LOG:
如上图看到:手机在进行SDP查询过程中,插电两个基于RFCOMM的协议,第一个是基于RFCOMM的HFP,channel为10;第二个是基于UUID:0xAABB的私有链路,channel 为29,接下来我们的大数据会基于这条私有RFCOMM链路进行传输。
RFCOMM 连接协商建立
1. 首先会进行RFCOMM PSM L2CAP连接:
2. 接着会进行Rfcomm Signaling连接:
从上图可以看到,Rfcomm连接的第一步是手机在在Channel 0上进行Signaling Connect,第一个包是RFCOMM SABM(Set Asynchronous Balanced Mode)进行同步,这是一个payload为0字节的命令包,耳机会回复一个控制包RFCOMM UA应答包,如下图:
这里注意一下DLCI就是数据链路连接标志的意思,有6个bit,也就是0-63,RFCOMM是支持多路复用的,DLCI ==0 是Signaling通道,也就是控制通道,DLCI == 1不可用,DLCI 2-61可用 ,也就是RFCOMM最多可以有60路连接。
3. RFcomm Parameters Negotiation
如上图首先是手机会在Signaling Channel上发起RFCOMM Parameter Negotiation Command,注意一下右边红色框里的参数:首先二者协商出来的DLCI是0x3A,也可以看到手机支持Credit-based Flow control,MTU为990字节,给耳机的最初Credit是7,也就是耳机在手机没有更新credit的情况下,一次最多发送7个数据包。
上图是耳机在Signaling Channel上回复手机的RFCOMM Parameter Negotiation Response,可以看到耳机是支持Credit-based Flow Control, MTU也是990字节,但耳机给手机的初始Credit为1,也就是手机最多发送一个包,然后就需要等待耳机的Credit更新。
4. RFCOMM CONNECT
这一步手机会连接在前面通过SDP协商获取的Server Channel 29 发起RFCOMM connect:
如上图,需要注意的时候,DLCI变成了0x3A,后面的数据交互都是在此DLCI上进行。
5. RFCOMM Modem Status
这一步就是进行状态协商,大概意思就是双方互相告诉对方,我已经准备好了,你可以发送数据了:
如上图手机会先在Signaling channel 上发起Modem Status command,告诉耳机我已经准备好通讯,准备好接收数据了。
上图是耳机回复给手机的Modem Status response,也是告诉手机,我已经准备好通信了,准备好接收数据了。
在此之后,耳机也会主动发起Modem Status Command,然后手机也会回复Modem Status Response。
RFCOMM传输数据
RFCOMM数据包的传输是通过UIH包(Unnumbered Information with header check)进行的,同时流控是基于Credit based Flow control方式:
从上图看到耳机给手机发了一个667字节的数据包,手机的接收buffer credit需要减1,也就是10-1=9。
从上图看到手机回复了一个10个字节的数据包,然后会有一个Given Credits == 1,表示手机已经处理好了上一个耳机发给手机的包,手机的接收buffer释放出了,需要加1,也就是9+1 =10;与此同时耳机的接收buffer需要减1,也就是1-1 = 0,意思是手机不能继续往耳机发送数据了。
从上图看到耳机处理完手机发过来的数据包,会回复一个0字节的应答包,这个包的唯一作用就是更新credit,告诉手机,你发给我的数据包我处理好了,我的接收buffer credit可以加1,也就是0 + 1 = 1。
总结
RFCOMM是一种适合传输大数据的蓝牙协议,比较简单,而且有流控协商,是在蓝牙开发中经常用到的传输协议。