三、Session Protocol
OBEX操作由request-response对组成。Request由client发出的,response由server发出的。Client发送一个request后,需要在收到来自server的response之后才能发送新的request。但是当启动OBEX Single Response Mode (SRM)时执行Put或者Get操作的时候也有例外的情况,在这种情况下,为了提高OBEX的吞吐量会忽略标准的request-response序列。
1、Request和Response的格式
(1)Request的格式:
Requests由一个或者多个packet组成,每个packet由1 byte的opcode、2 byte的packet length及其他数据组成(根据操作确定)组成
Opcode的最高位是Final位,当Final设置为1时表示这是request的最后一个包,例如:一个Put 操作发送一个很大的object时,需要发送多个Put包才能完成,但是只有最后一个Put包的Put opcode的Final设置为1
在server收到一个Final设置为1的request后,回复操作需要使用多个response包才能完成(例如:一个Get操作返回的object太大,一个response包无法容纳时),这时server将使用“Continue”response code告诉client继续发送request,client将使用同样的opcode发送request,但是opcode的Final bit需要设置为1且没有任何header。如果client不想继续操作,可以发送ABORT包
Packet length和header length一样,都是大端序,Packet length表示整个包的长度(包括opcode和packet length的3个byte)。最大值是64K-1。
Request code:
(2)Response的格式:
Response由一个或者多个packet组成,每个packet由1 byte的opcode、2 byte的packet length及其他数据组成(根据操作确定)组成。
Opcode的最高位也是Final位,在0BEX 1.0中,总是设置为1。含义与request的Final稍有不同,这里的Final bit用来告诉对方(client)轮到client发送packet了。如果response packet的response code是success或者failure,则client可以开始一个新的操作。如果response code是“Continue”,则client接下来将发出Get request的延续
Packet length和header length一样,都是大端序,Packet length表示整个包的长度(包括opcode和packet length的3个byte)。最大值是64K-1。实际的最大值需要根据OBEX CONNECT操作的协商确定
Response code定义如下:
2、Connect操作
Connect request和Connect response只能是一个单一的OBEX packet
Connect request(Client发送)格式如下:
Connect response(Server发送)格式如下:
(1)OBEX version number
高4 bit是主版本号,低4 bit是次版本号。当前版本号都是1.0,即0x10
(2)Flags,含义如下:
Connect request中flag是0x00,Connect response中bit 0表示server是否支持多个IrLMP连接导同一个LSAP-SEL。
(3)Maximum OBEX Packet Length
2 byte的无符号整型,用来表示设备可以接收的最大OBEX packet size。最大不能超过64K-1 byte,client和server可能有不同的值。OBEX packet size默认值是255 byte,在CONNECT packet中可以增大。注意:Maximum OBEX Packet Length>=255
(4)Response code
0xa0表示success,其他值表示failure,失败时可能有一个Description header用来描述失败原因。
举例:
Connect request:
(1)Opcode:0x80,connect request只有一个packet,所以设置final bit=1
(2)connect packet length:0x001A,即长度是26
(3)OBEX version number:0x10,即1.0
(4)flags:0x00,request的flags必须设置为0x00
(5)Maximum OBEX Packet Length:0x0430,即1072
(6)header:target header(0x46),这是PBAP的header:
Connect response:
(1)Opcode:0xA0,表示success
(2)connect response packet length:0x001F,即长度是31
(3)OBEX version number:0x10,即1.0
(4)flags:0x00,response的flags的bit 1位不支持Multiple IrLMP connections
(5)Maximum OBEX Packet Length:0x0430,即1072
(6)haeder:
Connection id(0xcb):0x00000001
Who header(0x4a):跟connect request中的Target header一样。
3、Disconnect操作
Disconnect request和Disconnect response只能是一个单一的OBEX packet
Disconnect request(Client发送)格式如下:
Disconnect response(Server发送)格式如下:
注意:client发送Disconnect request,server不能拒绝,必须回复Disconnect response
举例:
Disconnect request:
Disconnect response:
4、Put操作
OBEX连接建立后,client可以使用Put操作将object推送到server。Put request由一个或者多个packet组成(取决于传输的object的大小和OBEX packet的大小),如果没有设置OBEX Single Response Mode (SRM)为enabled,则server没收到一个Put request packet会回复一个response;如果设置SRM为enabled,则整个Put操作只需要一个response packet(即收到最后一个Put request packet后发出),除非server选择拒绝Put操作。
Put request(Client发送)格式如下:
Put response(Server发送)格式如下:
举例:
Put response:
5、Get操作
OBEX连接建立后,client可以使用Get操作从server获取object。如果设置OBEX Single Response Mode (SRM)是disable,则client每发送一个Get request packet会收到一个Get response packet;如果SRM是enable,则第一次发送Get request(可能包含多个Get request packet,但只有一个request packet的Final bit设置为1)即可。
Get request(Client发送)格式如下:
注意:如果server知道要传递什么,则Name header可以省略
Get response(Server发送)格式如下:
一个成功且一个response packet可以存放object的response code为0xa0(Success),如果回复的object太大需要多次Get request,则只有最后一个response的response code为0xa0即可,其他的response的response code为0x90(Continue),除了0xa0和0x90,其他的response code都表示failure。
Get request:
Get response(Continue):
Get response(Success):
6、Abort操作
当Client在muti-packet操作(例如PUT)正常结束前决定终止操作时,可以发送ABORT request。ABORT request和ABORT response都应该在一个OBEX packet里面其final bit设置为1。注意:client发送ABORT request后,如果没有收到ABORT response,则应该断开连接。
ABORT request(Client发送)格式如下:
ABORT response(Server发送)格式如下:
举例:
ABORT request
上面的图中解析有问题。可以看到request的opocde为0xff,packet length为0x08,header是Connection Id header=0xcb 0x00 0x00 0x00 0x01
ABORT response
7、SetPath操作
SETPATH操作用于在接收端设置“当前文件夹”,以便启用需要附加路径信息的数据传输。例如,当在两个设备之间发送一组嵌套的文件夹时,SETPATH用于在接收端创建文件夹结构。Path名称包含在name header中。每个SETPATH request和SETPATH response都应该在一个OBEX packet里面且Final bit设置为1。
SETPATH request(Client发送)格式如下:
SETPATH response(Server发送)格式如下:
注意:
如果server不支持SETPATH,应该回复C0(Bad Request)或C3 (Forbidden)。
当建立一个新的OBEX或TinyTP连接时,OBEX server的当前文件夹应该是根文件夹
(1)flags,定义如下图所示
(2)constants:设置为0x0
注意:
(1)使用Name header时,可以设置为:
<name>:表示从当前目录下进入名字为name的文件夹
<empty>:回到默认文件夹
(2)当使用flags或者constants指示路径时(例如设置flags的bit 1为1时,表示当前目录回退一个目录,即../),name header可以忽略。
举例:
SETPATH request
SETPATH response
四、OBEX在L2CAP上如何使用
1、蓝牙设备可以作为OBEX client或者server,也可以同时作为OBEX client和server,需要满足以下要求:
(1)在同一个蓝牙设备上的所有OBEX client和server需要有单独的L2CAP channel。因此在OBEX上的多路复用是不支持的。
(2)使用OBEX的应用协议需要在SDP database内注册service record,不同的应用协议的service record在各自协议中指定。
2、在接受OBEX client的connection request之前,OBEX server应该满足以下条件:
(1)OBEX server应该跟一个L2CAP PSM绑定,可以是固定的PSM,也可以是动态PSM
(2)使用OBEX server的应用协议应该将OBEX server的能力和相关的L2CAP PSM注册到SDP database内
(3)然后,OBEX server监听L2CAP连接及来自client的OBEX request
3、在L2CAP上接收OBEX packet
一个object可以通过一个或者多个OBEX Put request或者OBEX Get response进行交互。OBEX从L2CAP上接收packet,每个L2CAP SDU内包含一个OBEX packet。所有不能识别的packet或者无效长度的packet应该丢弃,如果SDU无效则可能需要断开L2CAP通道
4、client建立OBEX connection需要执行以下步骤:
(1)client使用SDP检索与OBEX server相关的信息(例如:L2CAP PSM)
(2)client使用L2CAP PSM建立和server之间的L2CAP channel
(3)client在L2CAP channel上向server发送OBEX Connect request
(4)如果client接收到来自server的connect response且结果是“Success”,则OBEX连接建立,否则OBEX连接建立失败。
5、断开OBEX连接
Client发送OBEX Disconnect request给server请求断开连接,收到response后,client应该关闭相关的L2CAP channel
五、OBEX v2.0以前的协议
1、架构图
OBEX是运行在RFCOMM上的。
2、OBEX在RFCOMM上怎么使用
(一)蓝牙设备可以作为OBEX client或者server,也可以同时作为OBEX client和server,需要满足以下要求:
(1)在同一个蓝牙设备上的所有OBEX server需要有单独的RFCOMM server channel。
(2)使用OBEX的应用协议需要在SDP database内注册service record,不同的应用协议的service record在各自协议中指定。
(二)在接受OBEX client的connection request之前,OBEX server应该满足以下条件:
(1)OBEX server应该打开一个RFCOMM server channel
(2)使用OBEX server的应用协议应该将OBEX server的能力注册到SDP database内
(3)然后,client搜索需要的server,server应该监听来自client的request
(三)client建立OBEX connection需要执行以下步骤:
(1)client使用SDP检索与OBEX server相关的信息
(2)client使用discovered RFCOMM channel建立RFCOMM连接
(3)client向server发送OBEX Connect request
(4)如果client接收到来自server的connect response且结果是“Success”,则OBEX连接建立,否则OBEX连接建立失败。
(四)断开OBEX连接
Client发送OBEX Disconnect request给server请求断开连接,收到response后,client应该关闭相关的RFCOMM channel