7. OBEX Examples
The following examples are provided to round out(更好的) the readers understanding of the procedures used in OBEX.
下面的例子是为了使读者更好地理解OBEX中使用的过程。
7.1 Simple Put - file/note/ecard transfer
This example describes a simple PUT operation, a scenario with many applications. It illustrates(说明) the basic request/response cycle, the exchange of version and capability information at the start of the connection, and the use of the Name and Length headers in the PUT operation.
这个列子描述了简单的PUT操作,说明了request/response,版本信息,功能信息,以及如何使用Name和Length header。
Ms. Manager worked up(制作了) an outline(大纲) for a presentation(演示文档) last night on her laptop(笔记本电脑), and needs to give it to a staffer(员工) to expand on(扩展,完善). She sets her laptop down next to an infrared adapter(红外设配器) attached to(属于) the staffer’s desktop machine, drags the Word document containing the outline to her OBEX app, and ...
A connection is made after her OBEX client queries staffer’s IAS to find the required LSAP of the staffer’s
OBEX application. In the first two examples, we will show the transaction byte by byte. For ease(容易) of
reading(易读性), the file and packet sizes are kept simple - file data is sent 1K at a time.
经理女士昨晚在她的笔记本电脑上为一个演示做了一个提纲,需要交给一名员工来进一步扩展。她把笔记本放在员工台式机的红外适配器的旁边,把提纲文件拖到OBEX app后,就建立了一个连接。在头2个例子里,按字节为单位去说明传输的过程,为了容易阅读,把每次传输的packet的大小设置为1K。
- client发送CONNECT packet(设置了final bit),包的大小是7字节,没有flag,以后包的最大字节数是8K,没有其他的header
- server返回0xA0(成功),包的大小是7字节,以后最大的response包的大小是2K,没有其他的header
- client发送PUT packet(由于不是最后一个packet,所以没有设置final bit),包的大小是1058字节(为什么是1058?)【opcode(1字节)+length(2字节)+name header(23字节)+length header(3字节) + body header(1027字节) = 1056字节】。
- name header(0x01):值为THING.DOC。HI(1字节)+length(2字节)+value(9个字符*2=18字节)+null terminated(2个字节)=23字节(0x17)
- length header(0xC3):值是object的大小,为24576(0x6000)字节。
- body header(0x48):body本身的大小是1K,加上body的HI(1字节)和header的长度(2字节),所以body header的整个大小是0x0403(1027字节)
- server返回0x90(CONTINUE),包的大小是3字节,没有其他的header
- client发送PUT packet(由于不是最后一个packet,所以没有设置final bit),包的大小是1030字节。
- body header(0x48):body本身的大小是1K,加上body的HI(1字节)和header的长度(2字节),所以body header的整个大小是0x0403(1027字节)
- server返回0x90(CONTINUE),包的大小是3字节,没有其他的header
A number of packets containing chunk of file body are sent, and finally we arrive at the last packet, which
has the Final bit set.
知道发送最后一个body header,final set被设置。
- client发送PUT packet(由于是最后一个packet,所以设置final bit),包的大小是1030字节。
- end-of-body header::body本身的大小是1K,加上body的HI(1字节)和header的长度(2字节),所以body header的整个大小是0x0403(1027字节)
- server返回0xA0(成功),包的大小是3字节,没有其他的header
The transaction is complete, so the OBEX client disconnects. 3 seconds have passed, and Ms. Manager
heads down(走向) the hall to a meeting. No Type header was used, so the server assumes a binary file and stores it exactly as is.
事务已完成,因此OBEX客户端断开连接。过了3秒钟,女经理走向会议大厅。没有使用类型头,因此服务器假设一个二进制文件并按原样存储。
7.2 Simple Get - field data collection
This example illustrates(说明) a GET operation with user defined headers, which, in this case, are for
application specific access identifier and version information.
A meter(仪表) keeps tabs(费用) on electricity(电) used, and is intermittently(间歇地) visited by a meter reader(抄表器). The meter reader points a collection device at the meter and presses a button which causes the following:
下面的例子说明是了使用user自定义header的GET操作。user自定义header里使用了特殊访问标识符和特殊的版本信息。抄表器会间歇地读电表的读数。抄表器放置了一个收集设备在电表上,并且按一个它上面的按钮,发送了下面的事情:
- client发送CONNECT packet(设置了final bit),包的大小是26字节,没有flag,以后包的最大字节数是2K,使用了user defined header,HI是0x70,长度是19字节,value是XUseElectricityX(16字节)
- server返回0xA0(成功),包的大小是11字节,以后最大的response包的大小是64K
- 自定义header:0xF0,值是0x00000603(仪表版本信息)
- client发送GET请求,设置了final bit,长度是3
- servre返回0xA0(成功),包的大小是0x38字节
- end-of-body header:长度是0x0035,body自体是0x32字节。
A security code ( “XUseElectricityX” ) was passed in a user defined header during connection to keep
prying(窥探) eyes at bay(陷入困境:at bay). The GET operation specified no Name or other headers, so the meter returned a reading. A header entry at this point might have instructed(指示) the meter to return service information. No Type or Name headers were needed on the returned object because the client application knows just what it is getting.
在连接过程中,在用户定义的报头中传递了一个安全代码(“xuseeelectricityx”),以防止窥探者进入。GET操作没有指定名称或其他标头,因此仪表返回读数。server没有必要返回name和type header,因为client知道它要什么。
7.3 Example Get of the Capability Object
This example shows a client requesting the capability object from a device. The OBEX packet size is 512
bytes。
这个例子展示了如何请求capability object。OBEX packet的大小是512字节。
7.4 Connect using Target, Who and Connection Id headers
Here is a PUT operation broken out with each component (opcode or header) on a separate line. We are
sending a file called jumar.txt, and for ease of reading, the example file is 4K in length and is sent in 1K
chunks. This illustrates the format of a directed Connection, using the Target, Who and Connection Id
headers. The connection was accepted by the Targeted application.
这个例子是发送一个叫jumar.txt文件的PUT操作,文件大小是4k,按1k的块发送。这里使用了Target ,Who,Connection id header。连接是定向连接。
- client发送CONNECTION操作,长度是0x0023字节。没有使用flag。能够接收的最大packet大小是8K。有header
- Target header:大小是19.UUID是0x382D2BD03C3911D1AADC0040F614953A(16字节)。
- length header:大小是0x0000F483字节。
- server返回0xA0(成功)。packet大小是35字节。能够接收的最大packet大小是2K
- Connection id header:值是0x00000001
- Who header:长度是0x0013.值是0x382D2BD03C3911D1AADC0040F614953A(16字节),它的值和client发送过来的Target header值相同。
- client发送PUT操作,此操作有1063个字节。
- connection id header:值是server返回的0x00000001
- name header:长度是0x0017.值是JUMAR.TXT.
- length header:值是0x00001000
- body header:body的长度是0x0403,后面是1k的body内容。
- server返回0x90(CONTINUE),packet长度是3字节,没有其他的header
- client继续发送JUMAR.TXT本体,一直到发送完毕。
- client发送DISCONNECT操作
- connection id header:值是server返回的0x00000001
- server返回0xA0(成功)。packet大小是3字节。
7.5 Combined Get and Put - paying for the groceries(杂货店付款)
Now that you have the idea of what the byte sequence looks like, we will represent the remaining
examples in a more readable format.
现在您已经知道字节序列是什么样子了,我们将用一种更可读的格式来表示其余的示例。
Smiling vacantly(毫无表情地), the checkout clerk(收银员) says “$45.12, please”. You take out your bit-fold (electronic bill-fold). You point it(对准) at the IR window(红外扫描器) at the checkstand(点货收款台 ), and press the “Do-it” key. An encrypted(加密的) IR connection(红外连接) is made to the register. During the connection negotiation(协商), you discover that the store takes Visa and the local bank’s debit card.
你拿出你的小折页(电子账单折)。你把它指向检查台的红外窗口,然后按“做”键。对寄存器进行加密的红外连接。在连接协商过程中,您发现该店使用Visa卡和当地银行的借记卡。
Request:
<opcode=Connect>
version info
encryption information
Response:
<response code = success>
version and capabilities info
encryption information
Accepted-payment-forms: Visa, MasterCard, ....
Request:
<opcode=Get> // Get with no arguments tells register to return itemized amount
Response:
<response code = success>
Type: text/itemized-receipt
Len: 2562 // wow, you bought a lot of items
The cash register chimes pleasantly as your payment is verified.
Response:
<response code = success>
Type: text
Len: 123
<hey, it says you got some frequent flyer miles!>
Connection disconnects, you pocket the bit-fold and head out past the stacks of dog food and charcoal
briquettes. At home you set the bitfold down by your PC and press the “Reconcile” key, and it connects to
your PC, sends the days purchases with itemized receipts over to the OBEX server. With a home
accounting program you make short work of the financial record keeping, since the data is all entered for
you, free of errors. Of course, it is harder to hide the purchase of the Twinkies from your spouse...
7.6 Create Session Followed by a Directed Connection
- client发送SESSION操作,packet长度0x0015字节
- Session-Parameters header:长度18字节。
- 第一个TLV:session opcode(0x05),length(0x01字节),value(0x00:创建session)
- 第二个TLV:Device address(0x00),length(0x04字节),value(0xXXXXXXXX)
- 第三个TLV:Nonce(0x01),length(0x04字节),value(0xYYYYYYYY)
- Session-Parameters header:长度18字节。
- server返回0xA0(成功),packet长度是0x0024字节。
- Session-Parameters header:长度33字节。
- 第一个TLV:Device address(0x00),length(0x04字节),value(0xXXXXXXXX)
- 第二个TLV:Nonce(0x01),length(0x04字节),value(0xYYYYYYYY)
- 第三个TLV:Session ID(0x02),length(0x10字节),value(0xZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ)
- Session-Parameters header:长度33字节。
- client发送CONNECT操作,packet是28字节。
- Session-Sequence-Number header:0x00
- Target header:长度是0x0013,值是0x382D2BD03C3911D1AADC0040F614953A
- server返回0xA0(成功),packet长度是0x0021字节。
- Session-Sequence-Number header:0x01
- Connection id header:0x00000001
- who header:长度是0x0013,值是0x382D2BD03C3911D1AADC0040F614953A(和client发送的Target header里的值相同)
7.7 Suspend a Session
Note that Session-Sequence-Number headers are not used when sending Session commands in an
active session.
-
client发送SESSION操作,packet长度0x0015字节
- Session-Parameters header:长度6字节。
- 第一个TLV:session opcode(0x05),length(0x01字节),value(0x02:挂起session)
- Session-Parameters header:长度6字节。
-
server返回0xA0(成功),packet长度为12字节。
-
Session-Parameters header:长度9字节。
-
第一个TLV:Timeout(0x04),length(0x04字节),value(0x000004B0:1200秒)
client没有发送Timeout TLV,说明client想没有挂起的时限,但是server回了Timeout TLV,是1200秒,所以取client和server的最小值,也就是1200秒。
-
-
7.8 Resume a Session
If a session was suspended using the SUSPENDSESSION command then resuming the session does not require retransmission(重传) of OBEX packets. If the session was suspended because the underlying transport was lost it might be necessary to retransmit packets. Three cases exist. The first case is when the last client request is lost. The second case is when the last server response is lost. The third case is when the client receives the last response but the server does not know if the client has received it (packets do not need to be retransmitted in this case). In the first case the client knows the server did not receive the request because the Next-Sequence-Number field in the response to the RESUMESESSION command indicates this, so the client will retransmit the command. In the second and third cases the server knows what to do based on the value of the Session-Sequence-Number field in the first packet sent by the client.The example below shows the sequence needed to resume the session. Retransmission(重传) of packets is not shown.
如果session是使用SUSPENDSESSION来挂起的,则不需要重传数据(因为没有数据丢失)。如果是因为传输层数据的丢失导致的session的挂起,则有可能需要重传数据。有三种情况。
- 第一种情况:client的最后一个reqeust,server没有收到,需要client重新传输。client可以从server对client的RESUMESESSION请求返回的Next-Sequence-Number得知,最后一个request,server没有收到。
- 第二种情况:server的最后一个response,client没有收到,需要server重新传输。server可以从client发送的RESUMESESSION请求里的Session-Sequence-Number来判断需要重传。
- 第三种情况:client接收到了server返回的最后response,但是server不知道client是否收到了。server可以从client发送的第一个packet里的Session-Sequence-Number来判断不需要重传。
下面的例子省略了重传的部分。
- client发送SESSION操作,packet大小是0x0027字节
- Session-Parameters header:大小0x0024字节
- 第一个TLV:session opcode(0x05),length(0x01字节),value(0x03:Resume Session)
- 第二个TLV:Device address(0x00),length(0x04字节),value(0xXXXXXXXX)
- 第三个TLV:Nonce(0x01),length(0x04字节),value(0xYYYYYYYY)
- 第四个TLV:Session ID(0x02),length(0x10字节),value(0xZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ)
- Session-Parameters header:大小0x0024字节
- server返回0xA0(成功),packet大小是0x0027字节。
- Session-Parameters header:长度是0x0024字节。
- 第一个TLV:Device address(0x00),length(0x04字节),value(0xXXXXXXXX)
- 第二个TLV:Nonce(0x01),length(0x04字节),value(0xYYYYYYYY)
- 第三个TLV:Session ID(0x02),length(0x10字节),value(0xZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ)
- 第四个TVL:Next Sequence(0x03),length(0x01字节),value(0x05)
- Session-Parameters header:长度是0x0024字节。
7.9 Close a Session
- client发送SESSION操作,packet大小是0x001B字节。
- Session-Parameters header:大小是0x0018字节。
- 第一个TLV:session opcode(0x05),length(0x01字节),value(0x01:Close Session)
- 第二个TLV:Session ID(0x02),length(0x10字节),value(0xZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ)
- Session-Parameters header:大小是0x0018字节。
- server返回0xA0(成功),packet大小是3字节。
7.10 Negotiate a Timeout
client和server协商timeout时间。
- client发送SESSION操作,packet大小是0x000F字节。
- Session-Parameters header:大小是0x000C字节。
- 第一个TLV:session opcode(0x05),length(0x01字节),value(0x04:Set Timeout)
- 第二个TLV:Timeout(0x04),length(0x04字节),value(0x000004B0:1200秒)
- Session-Parameters header:大小是0x000C字节。
- server返回0xA0(成功),packet大小是12字节。
- Session-Parameters header:大小是0x0009字节。
- 第一个TLV:Timeout(0x04),length(0x04字节),value(0x00000384:900秒)
- Session-Parameters header:大小是0x0009字节。
- client和server希望的timeout时间不相同,所以取最小值,也就是server的900秒。