OBEX 3. Session Protocol
The session protocol describes the basic structure of an OBEX conversation. It consists of a format for
the “conversation” between devices and a set of opcodes that define specific actions. The OBEX
conversation occurs within the context of an OBEX connection. The connection oriented session allows
capabilities information to be exchanged just once(只一次) at the start of the connection, and allows state information to be kept (such as a target path for PUT or GET operations).
session protocol描述了OBEX通信的基本结构。它由通信的报文和opcode(操作code)组成。OBEX通信发生在OBEX connection的上下文中。面向session的连接允许在连接开始时,只交换一次capabilities信息,并允许保留状态信息。(例如用于PUT或GET操作的目标路径)。
OBEX follows a client/server request-response paradigm(范式) for the conversation format. The terms(术语) client and server refer to the originator(发起者)/receiver(接收者) of the OBEX connection, not necessarily(必要的) who originated(起源于) the low level IrLAP connection. Requests are issued by the client (the party(某一方) that initiates the OBEX connection). Once a request is issued(发行), the client waits for a response from the server before issuing another request. The request/response pair is referred to as an operation.
OBEX使用client/server,request/response的范式。术语client是指连接的发起者,术语server是指连接的接收者。这里的发起者和接收者,不一定使用低级别IrLAP连接。client发起request(发起OBEX connection的一方)。一旦一个request被发行,这个client就会等server的response,等到response后才能发下一个request。request/response对就是一次operation。
In order to(为了) maintain(保持) good synchronization and make implementation simpler, requests and responses may be broken(被打散成) into multiple(多个) OBEX packets that are limited to a size specified at connection time. Each request packet is acknowledged(被确认) by the server with a response packet. Therefore, an operation normally looks like a sequence of request/response packet pairs, with the final pair specially marked. In general(一般来说),an operation should not be broken into multiple packets unless it will not fit into(装进去) a single OBEX packet.
为了保持良好的同步并使实现更简单,可以将请求和响应分成多个OBEX包,这些包的大小在连接时指定。每个request都会被server确认。因此,一次operation就像一系列request/response packet对,直到最后一个request/response被确认。一般来说,一次operation不会分成多个packet,除非不能装到一个packet里。
Each Request packet consists of an opcode (such as PUT or GET), a packet length, and one or more
headers, as defined in the object model chapter. A header must entirely(完整地) fit within(装进) a packet - it may not be split over(分开成) multiple packets. It is strongly recommended that headers containing the information describing the object (name, length, date, etc.) be sent before the object body itself. For instance, if a file is being sent, the file name should be sent first so that the file can be created and the receiver can be ready to store the contents as soon as they(文件内容) show up(出现).
每个request packet由3部分组成:opcode;packet的长度;一个或者多个header。同一个header不能被分割到不同的packet里。强烈建议,在发送object自身前,先发送object的描述(比如名字,长度,日期等)。比如发送一个文件前,最好先发送文件的名字,以便接收方可以提前准备,直到文件内容发过来。
However, This does not mean that all descriptive headers must precede any Body header. Description
headers could come at any time with information to be presented in the user interface, and in the future
intermediate(中间的) headers may be used to distinguish among multiple parts in the object body.
然而,并不是所有描述性的header都必须先于body。可以显示的描述性的header可以在任何时候过来。后过来的中间的header可以用来区分多个body的part。
The orderly sequence of request (from a client) followed by response (from a server) has one exception.
An ABORT operation may come in the middle of a request/response sequence. It cancels the current
operation.
请求(来自客户端)和响应(来自服务器)的有序序列有一个例外。一个中止操作可能发生在请求/响应序列的中间。它取消当前操作。
Each side of a communication link may have both client and server if desired(渴望), and thereby(从而) create a peer to peer relationship between applications by using a pair of OBEX sessions, one in each direction.However, it is not a requirement that a device have a both client and server, or that more than one session be possible at once. For example, a data collection device(数据收集设备) (say a gas meter(煤气表) on a house) might be a server only, and support only the GET operation, allowing the device to deliver(传递出) its information (the meter reading(仪表读数)) on demand(要求). A simple file send applet on a PC might support only PUT.
如果需要,通信链路的每一端可以同时是客户端和服务器,从而通过使用一对OBEX会话(每个方向一个)在应用程序之间创建对等关系。但是,并不要求设备同时是客户机和服务器,或者一次可以有多个会话。例如,房子里的煤气表只是server,只支持GET操作,会把仪表读数发送个要求的client。在PC里传递文件的小程序也只是server,只支持PUT操作。
3.1 Request format
Requests consist of one or more packets, each packet consisting of a one byte opcode, a two byte
packet length, and required(必须的) or optional(可选的) data depending on the operation. Each request packet must be acknowledged(承认) by a response. Each opcode is discussed in detail later in this chapter, including the number and composition(构成方式) of packets used in the operation. The general form of a request packet is:
一个请求包括一个或多个数据包,每个数据包包括一个字节的opcode,二个字节的包的长度,任意字节的headers。每个request必须被响应。opcode的详细信息会在下面的章节讨论,包括opcode的数字和构成。request的构成如下:
Byte 0 | Bytes 1,2 | Bytes 3 to n |
---|---|---|
opcode | packet length | headers or request data |
Every request packet in an operation has the opcode of that operation. The high order bit of the opcode is
called the Final bit. It is set to indicate the last packet for the request. For example, a PUT operation
sending a multi-megabyte(兆字节) object will typically(通常) require many PUT packets to complete, but only the last packet will have the Final bit set in the PUT opcode.
每个request packet都有一个opcode。opcode的最高位是有特殊作用的。一个PUT操作一般需要发送兆字节的数据,这些数据会分成多个request packet,只有最后一个request packet的opcode的最高位会被设置成1,其余的request packet的opcode的最高位都是0.
If the operation requires multiple response packets to complete after the Final bit is set in the request (as
in the case of a GET operation returning an object that is too big to fit in one response packet). The
server will signal this with the “Continue” response code, telling the client that it should ask for more. The
client (requestor) should send another request packet with the same opcode, Final bit set, and no
headers if it wishes to continue receiving the object. If the client does not want to continue the operation,
it should send an ABORT packet.
如果一个请求的操作,需要多个response packet才能完成的话(比如一个GET操作返回的object的size过大,导致必须放入多个object)。server会返回“Continue” response code,以告诉client,我还有数据没发完,请继续找我请求要数据。如果client还想把剩余的数据要出来,则必须在发送一个request packet,里面的opcode和上次相同,opcode的最高位要设置成1,并且不带任何header。这样一来,server就知道了,client想要上次还没返回完的数据。如果client不想要剩下的数据,则发送ABORT packet给server。
As with(和。。。一样) header lengths, the packet length is transmitted(传输) in network byte order (high order byte first), and represents(表示) the entire length of the packet including the opcode and length bytes. The maximum packet length is 64K bytes - 1.
和header是length一样,packet的length也是按照网络字节序传输。packet的length表示整个packet的大小,包括opcode和length和headers。它的最大值是64K bytes-1(2的16次方-1).因为length占2个字节,所有是2的16次方。
3.2 Response format
Responses consist of one or more packets - one per request packet in the operation. Each packet
consists of a one byte response code, a two byte packet length, and required or optional data depending
on the operation. Each response code is listed later in this chapter, and commonly used codes are
discussed in the individual opcode sections. The general form of a request packet is:
response由1个或多个package组成。每个response packet包含:一个字节的response code;二个字节的packet length和响应数据。所有的response code列表在后面的章节,经常使用的codes会单独说明。格式如下:
Byte 0 | Bytes 1,2 | Bytes 3 to n |
---|---|---|
response code | response length | response data |
The high order bit of the response code is called the Final bit. In OBEX 1.0 it is always set for response
packets. Its meaning(意味着) is slightly(稍微) different from the request packet final bit—the response packet final bit tells the other side (the client) that it is once again(再次) the client’s turn to send a packet. If the response packet carries a success or failure response code, the client is free to begin a new operation. However, if the response code is “Continue” as is often the case(这是经常发生的case) in a lengthy(很长的) GET operation, then the client next issues a continuation(延续) of the GET request. See the GET operation description below for examples.
response code的高位叫做Final bit。在OBEX1.0里,这个高位的值一直是1.response code的高位的值为1,和request 的opcode的高位值是不同的含义。response code的高位的值为1,就是告诉client,你可以再次发request packet了。如果response packet返回的结果是成功或者失败,则client就可以开始发起新的operation了。然而,如果response code是“Continue”,这是经常发生的情况,在一个很长的GET操作里,则client要继续发送后续的GET request。关于GET的具体操作,看下面的例子。
As with(和。。。一样) header and request lengths, the response length is transmitted in network byte order (high order byte first), and represents the entire length of the packet including the response code and length bytes. The maximum response packet length is 64K bytes - 1, and the actual length in a connection is subject to(受。。。支配:be subject to) the limitations(限度) negotiated(协商) in the OBEX CONNECT operation.
和header是length一样,response 的length也是按照网络字节序传输。response 的length表示整个packet的大小,包括response code 和length和response data。它的最大值是64K bytes-1(2的16次方-1).因为length占2个字节,所有是2的16次方。实际的大小是在连接创建时指定的。
The (optional) response data may include objects and headers, or other data specific to(针对) the request that was made. If a Description header follows the response code before any headers with object specific information(具体信息), it is interpreted as(被解释为:be interpreted as) descriptive(描述性的) text expanding on(更充分的阐述) the meaning of the response code. Detailed responses are discussed in the opcode sections below.
response data里包含object和header,或者针对请求的其他object。如果Description header是跟在response code后面的第一个header的话,这个response就被解析为描述性的response。具体的response后面讨论。
The response code contains the HTTP status code (a 3 digit ASCII encoded positive integer(正数)) encoded in the low order 7 bits as an unsigned integer (the code in parentheses(圆括号) has the Final bit set). See the HTTP document for complete(完整的) descriptions of each of these codes. The most commonly used response codes are 0x90 (0x10 Continue with Final bit set, used in responding to non-final request packets), and 0xA0(0x20 Success w/Final bit set, used at end of successful operation).
response code是用http status code表示的,也就是3位的十进制正整数。由于response code就占一个字节,而且最高位还永远是1,所以只能用后7个bit来表示。所以当response code是0x90时,去掉最高位的1,就变成了0x10,0x10是Continue的意思。0xA0去掉最高位,就变成了0x20,就是Success的意思。
3.3 OBEX Operations and Opcode definitions
OBEX operations consist of the following:
The high bit of the opcode is used as a Final bit, described in the previous sections of this chapter. Bits 5
and 6 of the opcode are reserved for future use and should be set to zero by sender and ignored by
receiver. However, one notable(值得注意的) exemption(例外) from this rule is the ABORT opcode, which currently sets bits 5 and 6.
opcode的最高位用于做Final bit,在前面已经说明过了。第五个和第六个bit位是保留位,为后续的扩展保留。所以发送方应该把bit 5和bit 6设置为,且接收方会忽略这2位。然而有个值得注意的例外,就是ABORT opcode,ABORT opcode会设置bit 5和bit 6.
If a server receives an unrecognized(无法识别的) opcode, it should return 0xD1 response code (Not Implemented, with Final bit set) and ignore the operation. It may send the request to the bit bucket, save it for later analysis, or whatever it chooses.
如果server收到了无法识别的opcode,它应该返回0xD1 response code(但是这个没有被实现)并忽略此operation。server可以给bit bucket发送请求,留着以后分析,或者做它(server)想做的。
Each operation is described in detail in the following sections
每个operation都会在后续详细介绍。
3.3.1 Connect
This operation initiates the connection and sets up the basic expectations(基本期望) of each side of the link. The request format is:
此操作启动连接,并设置链路每侧的基本期望值。这个请求格式为:
Byte 0 | Bytes 1 and 2 | Byte 3 | Byte 4 | Bytes 5 and 6 | Byte 7 to n |
---|---|---|---|---|---|
0x80 | connect packet length | OBEX version number | flags | maximum OBEX packet length | optional headers |
The response format is:
Byte 0 | Bytes 1 and 2 | Byte 3 | Byte 4 | Bytes 5 and 6 | Byte 7 to n |
---|---|---|---|---|---|
response code | connect response packet length | OBEX version number | flags | maximum OBEX packet length | optional headers |
The CONNECT request and response must each fit in a single packet. Implementations are not required
to recognize more than the first 7 bytes of these packets, though this may restrict(限制) their usage.
CONNECT 操作的request和response必须放在一个packet里。实现的程序只需要读取7个bit就好,虽然只读7个会限制了灵活性。
3.3.1.1 OBEX version number
The version number is the version of the OBEX protocol encoded with the major number(主版本号) in the high order 4 bits, and the minor version(小版本号) in the low order 4 bits. The protocol version is not always the same as the specification(规范) version. The current protocol version is 1.0. See the example later in this section.
版本号指的是OBEX协议的版本号,主版本号用高4位标识,小版本号用低4位标识。实际使用的版本和规范的版本可能是不同的。
3.3.1.2 Connect flags
The flags have the following meanings:
bit | Meaning |
---|---|
0 | Response: Indicates support for multiple IrLMP connections to the same LSAP-SEL.表示支持同一个LSAP-SEL的多个LrLMP连接。Request: reserved 保留 |
1 | Reserved保留 |
2 | Reserved保留 |
3 | Reserved保留 |
4 | Reserved保留 |
5 | Reserved保留 |
6 | Reserved保留 |
7 | Reserved保留 |
All request flags except bit 0 are currently reserved, and must be set to zero on the sending side and
ignored by the receiving side. All reserved response bits must also be set to zero and ignored by the
receiving side.
除了bit 0以为,所以的response flag都是保留位,所以发送端必须把这些保留位设置位0,而接收端必须忽略这些保留位。
In a CONNECT Response packet bit 0 is used to indicate the ability of the OBEX server’s transport to
accept multiple IrLMP connections to the same LSAP-SEL. This capability, usually found in more robust(健壮的)IrDA stacks, allows the server to use the LM-MUX for multiplexing(多路复用) multiple simultaneous(同时的,同步的) client requests. Conveying(传递出) this information is necessary because the IrDA Lite specification does not support this type of multiplexing and attempts to connect to an already connected LSAP-SEL will result in an IrLAP disconnect.
CONNECT Response packet的bit 0被用来指出OBEX server是否支持:在同一个LSAP-SEL里可以使用多个IrLMP 连接的功能。这个功能经常出现在IrDA的协议栈中。允许server使用LM-MUX的多路复用功能,去满足多个client的请求。标识出server是否支持这个功能是非常有必要的,由于IrDA Lite规范不支持这种多路复用,而且去连接一个已经存在LSAP-SEL就会导致断开了IrLAP连接。
Bit 0 should be used by the receiving client to decide how to multiplex(多路复用) operations to the server (should it desire to do so). If the bit is 0 the client should serialize(连载,连播) the operations over a single TTP connection. If the bit is set the client is free to establish(建立) multiple TTP connections to the server and concurrently (并发地)exchange its objects.
client会查看返回的packet里的bit 0,来决定是否可以使用多路复用(如果它希望这么做)。如果bit 0的值是0,则client只在一个TTP连接上连续传递数据。如果值是1,则client会建立多个TTP连接,并且可以并发地交换数据。
3.3.1.3 Maximum OBEX Packet Length
The maximum OBEX packet length is a two byte unsigned integer that indicates the maximum size OBEX
packet that the device can receive. The largest acceptable value at this time is 64K bytes -1. However,
even if a large packet size is negotiated(协商), it is not required that large packets be sent - this just represents the maximum allowed by each participant(参与者). The client and server may have different maximum lengths.
OBEX packet的最大值是2个字节的无符号整数,表示可以传递的最大size。由于是2个字节所以最大值是64K - 1.然而,即使协商了一个大的size,也不是必须要发这个大的packet,它仅仅是允许的最大值而已。client和server可以有不同的最大值。
This is one of the most important features of the CONNECT packet because it permits(许可) the application to increase the OBEX packet size used during an exchange. The default OBEX packet size of 255 bytes is inefficient(效率低下的) for large object transfers and will impede(妨碍) transfer rates(传输速率). Larger OBEX packet sizes such as 8k to 32k allow large amounts of data to be sent without acknowledgement(确认). However, packet sizes should be intelligently(智能地) limited on slower links to reduce(减少) abort request latency(终止请求延迟).
这是非常重要的CONNECT功能,因为application可以指定其大小。默认是是255 byte,对于大的object传输来说,这是非常效率低下的,而且会妨碍传输速率。稍微大点的OBEX packet(8k到32k)可以传输很多data,而且不需要被server确认。然而,packet的大小不是一层不变的,应该被传输速度慢的链路自动调整,以减少终止请求延迟。
3.3.1.4 Minimum OBEX Packet Length
The minimum size of the OBEX Maximum packet length allowed for negotiation is 255 bytes. This is in
order to(为了) provide a greater likelihood(可能性) of meeting(满足) the requirement for single packet requests and responses in a broad range of cases. In addition, since(由于) an OBEX header must fit completely within one OBEX packet it is advantageous to(对。。。有好处) mandate(授权) a minimum that allows for(考虑到) reasonable(合理的) header sizes. Note that OBEX does not exchange Minimum Packet Length values. This value is the minimum acceptable value for the OBEX Maximum Packet Length parameter exchanged in the CONNECT Operation。
第一句是不是写错了,应该是The Maximum size of the OBEX Maximum packet length allowed???
3.3.1.5 Using Count and Length headers in Connect
The Count and Length headers, defined in the Object Model chapter, can be used in CONNECT. Count
is used to indicate the number of objects that will be sent during this connection. Length is used to
express the approximate(近似的) total length of the bodies of all the objects in the transaction.
When used in the CONNECT Operation, the Length header contains the length in bytes of the bodies of
all the objects that the sender plans to send. Note that this length cannot be guaranteed(担保的,放心的) correct, so while the value may be useful for status indicators and resource reservations(保留), the receiver should not die if the length is not exact. The receiver can depend on Body headers to accurately(准确地) indicate the size of an object as it is(实际上:as it is) delivered and the End-of-Body header to indicate when an object is complete.
Count和Length header可以用在Connection操作里,Count header被用作标识出要传输的object的数量。Length可以用于表示要传输的body总和的近似大小。当Length用在Connection操作里时,单位是字节,值是打算传输的所有body总和。要注意虽然Length的值不是百分百正确的,所有这个值可以用于状态标识(status indicators)和资源保留,但是接收方不能因为Length值的不准确,导致自己程序出现致命错误而死机。接收方可以根据Body header来得知实际被传递的object的准确大小,而且可以根据End-to-Body来得知object何时全部传输结束。
3.3.1.6 Using Who and Target headers in Connect
Target and Who are used to hold a unique identifier, which allows applications to tell whether they are
talking to a strict(严选的) peer, or not. Typically, this is used to enable additional capabilities supplied only by an exact peer. If a Who header is used, it should be sent before any body headers.
Target和Who头,用于保持一个唯一的标识符,这样一来,application就可以根据Target和Who的值来判断对方是否需要特殊对待。如果要使用Who头,必须在所有body header之前。
On full-featured [PC] platforms, multiple OBEX applications may exist concurrently. This leads to(导致了) the need for the client to be able to uniquely identify which server it wants to handle its request. The server is therefore identified with the OBEX Target header. If necessary, the client can also identify itself, using the
OBEX Who header. The following text describes the exact uses of these headers.
在PC上有可能存在多个并发的OBEX application。这就导致client必须要指定访问哪个server。所以就用Target来指示出要访问哪个server。如果有需要,client可以使用Who头来告诉server,自己是谁。
To target a specific application with OBEX commands the client must set-up a connection to the
application by using the OBEX Target header in a CONNECT request. This type of connection is called a
directed connection and provides a virtual binding between the client and server. The Target header
should specify the UUID of the desired application. The Who header can also be used when it is
necessary to identify the client initiating the exchange. The Who header should be used in cases where
the target server application supports different client applications and may care which one it is connecting
to. It is unnecessary to send a Who header in the request if its only logical value is the same as the
Target header.
为了用OBEX,访问一个指定的application,client必须使用Target头,来建立和这个application的连接。这种连接叫做定向连接,并且提供一个虚拟的绑定,在client和server之间。Target头了的值是要访问的application的UUID。如果有需要,client也可以使用Who告诉server自己是谁。由于server可能可以服务于多个client application,所以server必须知道正在于之通信的,是哪个application的client。如果who头的值和target的值相同,则没有必要发送who头了。
The response to the targeted connect operation should contain a Who with the same UUID as sent in the
request’s matching Target header. If the Who header was present in the request, a Target header
identifying the same client should be sent in the response. In addition, a unique connection identifier must
be sent in a Connection Id header. This connection identifier is used by the client in all future operations.
If the response does not contain the correct headers then it should be assumed that the connection has
not been made to the specific application but to the inbox service. This will be the response when sending
a directed connect to a system that does not parse these (Target) headers. In the event that a connection
is made to the inbox service, it is the responsibility(责任) of the client application to determine whether to continue the exchange or disconnect.
针对于使用了Target头的request,response里应该包含who头,而且值应该和client发送过来的Target一样。针对于使用了Who头的request,response里应该包含target头,而且值应该和client发送过来的who一样。除此之外,在response里必须有Connection id头。client会在后续使用此connection id头。如果response里没有包含正确的头,就假设这个连接不是和特定的application建立的,而是和inbox service建立的。当将有Target头的packet发给server,但这个server并不解析这个Target头的话,就会产生response里不包含正确头的情况(上一句话的内容)。当建立的连接不是定向连接而是inbox service的连接的话,需要由client application来决定是否继续发送数据,还是断开连接。
3.3.1.7 Using Description headers in Connect
The CONNECT request or response may include a Description header with information about the device
or service. It is recommended this information be presented(表示) through the user interface on the receiving side if possible.
Connect操作的request和response里都可以包含设备和service的详细信息。如果可能,强烈建议由接收方表示描述头里的信息。
3.3.1.8 The Connect response
The successful response to CONNECT is 0xA0 (Success, with the high bit set) in the response code,
followed immediately by the required fields described above, and optionally by other OBEX headers as
defined above. Any other response code indicates a failure to make an OBEX connection. A fail response still includes the version, flags, and packet size information, and may include a Description header to
expand on the meaning of the response code value.
response code:0xA0,意味着连接成功建立。其他的response code都是连接建立失败。即便连接建立失败,response里也会返回version,flags,和packet size,并且可以包含描述头,去解释response code值的含义。
3.3.1.9 Example
The following example shows a CONNECT request and response with comments explaining each
component. The CONNECT sends two optional headers describing the number of objects and total
length of the proposed transfer during the connection.
3.3.1.10 OBEX Operations without Connect
It is highly recommended that implementations assume(假定) default values for connection parameters
(currently just a minimum OBEX packet size of 255 bytes) and accept operations such as PUT and GET
without first requiring(需要) a CONNECT operation.
强烈建议OBEX的实现代码,设置连接参数的默认值,并可以在没有连接的情况下,也可以处理PUT和GET请求。
3.3.2 Disconnect
This opcode signals the end of the OBEX session. It may include a Description header for additional
user readable information. The DISCONNECT request and response must each fit in one OBEX packet
and have their Final bits set.
Byte 0 | Bytes 1, 2 | Bytes 3 to n |
---|---|---|
0x81 | packet length | optional headers |
The response to DISCONNECT is 0xA0 (Success), optionally followed with a Description header. A
DISCONNECT may not be refused. However, if the disconnect packet contains invalid information, such
as an invalid Connection Id header the response code may be “Service Unavailable” (0xD3). Server side
handling of this case is not required.
Byte 0 | Bytes 1, 2 | Bytes 3 to n |
---|---|---|
0xA0 or 0xD3 | response packet length | optional response headers |
It is permissible(允许的) for a connection to be terminated by closing the transport connection without issuing the OBEX DISCONNECT operation. Though, this precludes(使。。行不通) any opportunity to include descriptive information about the disconnection. Currently, this is common practice and DISCONNECT is infrequently(很少)used. However, it is good practice to send an OBEX DISCONNECT for each OBEX CONNECT sent but few applications track or care about such details.
即便不使用Disconnect操作,也可以通过关闭传输上的连接来达到Disconnect操作的作用。但是这么做就没有机会发送关于关闭连接的描述性的header。最近大家都不用disconnect操作了。然而,发送disconnect操作也是很好的。
3.3.3 Put
The PUT operation sends one object from the client to the server. The request will normally have at least
the following headers: Name and Length. For files or other objects that may have several dated(注明日期) versions, the Date/Time header is also recommended, while the Type is very desirable(值得做的) for non-file object types. However, any of these may be omitted(省略) if the receiver can be expected(被期望) to know the information by some other means. For instance, if the target device is so simple that it accepts only one object and prevents(阻止)connections from unsuitable(不恰当的) parties(方), all the headers may be omitted(忽略) without harm(即便被忽略也没有任何副作用). However, if a PC,
PDA, or any other general-purpose(多功能) device is the intended(计划的) recipient(接收方), the headers are highly recommended.
PUT操作会发送一个object从client到server。request里一般至少包含Name和Length。文件或其他的object可能还需要Date/Time头。但是非文件object也是值得这么做的。然而上面说的header都可以被省略。例如,对方设备特别简单,以至于只接收一个object,并且阻止不合法的连接,即便忽略这些头,也不会有任何副作用。然而如果是pc,pda,和其他的多功能设备的话,强力建议使用上面提到的头。
A PUT request consists of one or more request packets, the last of which has the Final bit set in the
opcode. The implementer may choose whether to include an object Body header in the initial packet, or
wait until the response to a subsequent(后续的) packet is received before sending any object body chunks.
一个PUT request包含一个或多个packet,最后的packet的opcode的Final bit会被设置为1.实现的程序可以选择:是否发送body header在第一个packet里,也可以在发送body header之前,等待server回一次response后,在发送后续的body header。
Byte 0 | Bytes 1, 2 | Bytes 3 to n |
---|---|---|
0x02(0x82 when Final bit set) | packet length | sequence of headers |
Each packet is acknowledged by a response from the server as described in the general session model
discussion above.
每个request packet都要被响应。
Byte 0 | Bytes 1, 2 | Bytes 3 to n |
---|---|---|
Response code typical values:0x90 for Continue;0xA0 for Success | Response packet length | optional response headers |
3.3.3.1 Headers used in Put
Any of the headers defined in the Object model chapter can be used with PUT. These might include
Name, Type, Description, Length, Connection Id, HTTP or other headers specifying compression(指定压缩),languages, character sets(字符集), and so on. It is strongly recommended that headers describing the object body precede(在。。。之前出现) the object Body headers for efficient handling on the receive side. If Name or Type headers are used, they must precede all object Body headers.
任何header都可以出现在PUT操作里。强烈建议使用描述body object的header,并放在所以body header之前,这样做的好处是方便接收方的处理。如果使用了Name或者Type头,必须把它们放在所有body header之前。
3.3.3.2 Put Response
The response for successfully received intermediate(中间的) packets (request packets without the Final bit set) is 0x90 (Continue, with Final bit sent). The successful final response is 0xA0 (Success, with Final bit set). response to any individual(单独的) request packet must itself consist of just one packet with its Final bit set -multi-packet responses to PUT are not permitted.
对client发送过来的中间的packet的响应如果是成功的话,则response code为0x90(继续的含义)。对client发送过来的最后一个packet的响应如果是成功的话,则response code为0xA0(成功的含义)。针对任何单独的request packet的响应都必须在一个packet里,并且设置Final bit。多个响应packet对一个请求packet是不允许的。
Any other response code indicates failure. If the length field of the response is > 3 (the length of the
response code and length bytes themselves), the response includes headers, such as a Description
header to expand on the meaning of the response code value.
其他的response code都代表发生了错误。由于response code占一个字节,response length占2个字节,加起来是3个自己,所以如果response本身的长度大于3个字节,则说明此response包含了header,有可能是描述头,为了解释response code的含义。
Here is a typical Final response:
3.3.3.3 Put Example
For example, 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.
举例说明,下图是一个PUT的操作。要发送一个加
.txt的文件,为了易读性,这个文件的大小是4K,以1K大小发送,也就是需要发4次。
Another packet containing(包含) the next chunk of body is sent, and finally we arrive at the last packet, which has the Final bit set.
3.3.3.4 Server side handling of Put objects
Servers may do whatever(做什么都行) they wish with an incoming object(传入的object) - the OBEX protocol does not require any particular treatment. The client may “sugest” a treatment for the object through the use of the Target and Type Headers, but this is not binding on the server. Some devices may wish to control the path at which the object is stored (i.e. specify folder information such as C:\bin\pizza.txt rather than just pizza.txt). Path information is transferred using the SETPATH operation, but again, this is not binding on the server. It is important that clients, who have a particular purpose(特殊用途) in mind when transferring an object, connect to a specific service that it knows can perform the desired(渴望的) behavior.
server可以对传入进来的object做任何处理。OBEX 协议不需要做任何特殊的处理。client通过target和type头,告诉server,请特殊对待我,但server是否会特殊对待它,取决于server的实现代码。一些设备希望控制文件的存储路径。Path(路径)信息,可以使用SETPATH操作来发送,但是server是否处理,取决于server的实现代码。有一点非常重要,当client要发送一个特殊的请求时,一定要预先知道server是否能够处理。
3.3.3.5 Sending objects that may have read errors
When sending the last portion(部分) of an object in an End-of-Body header, ambiguity(歧义) arises(发生) if there is any chance that there are read errors in this last portion. This is because the End-of-Body normally triggers(触发)the receiving side to close the received object and indicate successful completion. If an ABORT packet subsequently(随后) arrives, it is “too late”.
The recommended(建议的) approach(方法) when sending objects which may have such errors is to send the End-of-Body header only when the sender knows that the entire object has been safely read, even if this means sending an empty End-of-Body header at the end of the object. This applies to both GET and PUT operations.
当设备发送 End-of-Body时,有可能设备发生故障。但是接收端已经收到 End-of-Body的一部分,接收端就不会继续接收数据。发送端发现没有全部把数据发出去后,想要给接收端发送ABORT,但是接收端已经不接收数据了,所以ABORT操作就无法送达。建议的解决方法是,发送方确认全部发送成功后,最后发一个空的 End-of-Body就可以了。GET和PUT都可以这么做。
3.3.3.6 Put-Delete and Create-Empty Methods
A PUT operation with NO Body or End-of-Body headers whatsoever(用于名词词组后,加强否定陈述)丝毫 should be treated as a delete request. Similarly, a PUT operation with an empty End-of-Body header requests the recipient(接收方) to create an empty object. This definition may not make sense(合乎情理) or apply to every implementation (in other words devices are not required to support delete operations or empty objects),A folder can be deleted using the same procedure used to delete a file. Deleting a non-empty folder will delete all its contents, including other folders. Some servers may not allow this operation and will return the “Precondition Failed” (0xCC) response code, indicating that the folder is not empty. In this case, the client will need to delete the contents before deleting the folder.
PUT操作定义:没有Body或者End-of-Body headers的request,被视为delete request。End-of-Body header 里没有内容的话,PUT操作就是要求接收方创建一个空的object。这个定义可能不合理,或者并不是所有的实现代码都支持此定义。换句话说设备没有义务去支持delete操作或者创建空的object操作)。删除文件夹和产出文件的procedure是一样的。删除空文件夹的同时,也不把里面的文件和子文件夹也删除掉。有的server不允许这种操作,会返回 “Precondition Failed” (0xCC) response code,以告诉client,这个文件夹里还有东西,删除文件夹前,先把里面的东西删除干净。
3.3.4 Get
The GET operation requests that the server return an object to the client. The request is normally
formatted as follows:
GET操作,要求server返回一个object给client。格式如下:
Byte 0 | Bytes 1, 2 | Bytes 3 to n |
---|---|---|
0x03 | Packet length | sequence of headers |
The Name header can be omitted(省略) if the server knows what to deliver, as with(就像。。。一样) a simple device that has only one object (e.g. a maintenance record(维修记录) for a machine(机器)). If the server has more than one object that fits(满足) the request, the behavior is system dependent, but it is recommended that the server return Success with the “default object” which should contain information of general interest(兴趣) about the device.
如果server知道要deliver什么的话,就可以省略name header。就像只有一个object的设备,它知道要deliver什么,不需要由name header告诉它(比如机器的维修记录)。但如果由多个object都满足request的要求,具体返回哪个object则由具体的系统决定。这种情况,一般建议server返回一个default object,这个object包含了通用的信息。
The final bit is used in a GET request to identify the last packet containing headers describing the item
being requested, and the request phase(阶段) of the GET is complete. The server device must not begin
sending the object body chunks until the request phase is complete. Once a GET is sent with the final bit,
all subsequent GET request packets must set the final bit until the operation is complete.
server不可以开发发送body chunks,在request全部传送到server端之前。一旦request的final bit被设定,则后续的request的final bit也一定要设定,直到对端返回0xA0为止。
A successful response for an object that fits entirely in one response packet is 0xA0 (Success, with Final
bit set) in the response code, followed by the object body. If the response is large enough to require
multiple GET requests, only the last response is 0xA0, and the others are all 0x90 (Continue). The object
is returned as a sequence of headers just as with PUT. Any other response code indicates failure.
Common non-success responses include 0xC0 bad request, and 0xC3 forbidden. The response may
include a Description header (before the returned object, if any) to expand on the meaning inherent(固有的) in the response code value.
处理成功返回的response code是0xA0,后面是object body。如果response packet过大,以至于需要多个request,只有最后一个packet里的response code是0xA0,其余的是0x90(继续)。返回的object是一个header序列,和PUT一样。0xA0和0x90以外的都是代表失败,失败时,返回的packet里可以加一个description header,来告诉client,为什么失败了。
Byte 0 | Bytes 1, 2 | Bytes 3 to n |
---|---|---|
response code | Response packet length | optional response headers |
A typical multi-step(多步骤) GET operation proceeds(处理) as follows: the client sends a GET request that may include a Name header; server responds with 0x90 (Continue) and headers describing the name and size of the object to be returned. Seeing the Continue response code, the client sends another GET request (with final bit set and no new headers) asking for additional data, and the server responds with a response packet containing more headers (probably Body Headers) along with(随同) another Continue response code. As long as(只要) the response is Continue, The client continues to issue GET requests until the final body information (in an End-of-Body header) arrives, along with the response code 0xA0 Success。
一个典型的GET操作处理,描述如下:
- client发送GET请求,可以包含Name header
- server返回0x90(继续)和header序列
- client看到返回的0x90,则client继续发送GET请求(设置了final bit,并且里面没有新的header),让server返回剩下的数据;server返回0x90(继续),并随同更多的header(有可能有body header)
- 只要server返回的是0x90(继续),则client就继续发送GET请求(必须设置final bit),直到接收到0xA0为止。
3.3.4.1 The default GET object
Refer to chapter 8.4 OBEX Get Default Object for more information on providing default objects. This
chapter defines a mechanism(机制) by which the client can request a specific type of default object. Such as the default business card or web page.
3.3.5 Abort
The ABORT request is used when the client decides to terminate a multi-packet operation (such as PUT)
before it would normally end. The ABORT request and response each always fit in one OBEX packet and
have the Final bit set. An ABORT operation may include headers for additional information, such as a
Description header giving the reason for the abort. Since(因为) there can only be one OBEX operation in
progress at a time, the use of a Connection Id header to abort a directed multi-packet operation is
optional.
在一个操作正常终止前,client可以发送一个ABORT请求,告诉sever,我要提前断开连接了。ABORT request和response都能够放在一个OBEX packet里,并都设置了final bit。ABORT操作也可以包括一些header,比如description header,来说明要提前终止的原因。因为在同一个时间点只能处理一个OBEX operation,所有使用Connection id header来终止定向的多个packet的操作是可选的。
Byte 0 | Bytes 1, 2 | Bytes 3 to n |
---|---|---|
0xFF | Packet length | optional headers |
The response to ABORT is 0xA0 (success), indicating that the abort was received and the server is now
resynchronized(重新同步) with the client. If anything else is returned, the client should disconnect.
Byte 0 | Bytes 1, 2 | Bytes 3 to n |
---|---|---|
0xA0 | Response packet length | optional response headers |
3.3.6 SetPath
The SETPATH operation is used to set the “current folder” on the receiving side in order to enable
transfers that need additional path information. For instance, when a nested(嵌套的) set of folders is sent between two machines, SETPATH is used to create the folder structure on the receiving side. The Path name is contained in a Name header. The SETPATH request and response each always fit in one OBEX packet and have the Final bit set.
SETPATH请求用于设定server端的当前文件夹,以便往这个文件夹里放数据。比如,要传输一个带子文件夹的数据,SETPATH 请求用于在server端创建此文件夹的结构。路径名放在name header。SETPATH请求和响应都能够放入一个OBEX packet里,并设置final bit。
Byte 0 | Bytes 1, 2 | Byte 3 | Byte 4 | Byte 5 to n |
---|---|---|---|---|
0x85 | Packet length | flags | constants | optional headers |
Byte 0 | Bytes 1, 2 | Bytes 3 to n |
---|---|---|
response code | Response packet length | optional response headers |
Servers are not required to store objects according to(根据) SETPATH request, though(尽管) it is certainly(当然) useful on general-purpose devices(通用设备) such as PCs or PDAs. If they do not implement SETPATH, they may return C0 (Bad Request) or C3 (Forbidden), and the client may decide whether it wishes to proceed.
server不是必须根据SETPATH请求来缓存数据,虽然在通用设备上(PC,PDA等),这样做法很有用。如果server没有实现SETPATH要件,它们会返回C0或者C3,有client来决定后续如何处理。
When a new OBEX or TinyTP connection is established, the OBEX server’s current folder should be its
root folder. In this manner(以这种方式) a device may retrieve (or serve) objects from the root folder without requiring the client to perform a SETPATH to the root first.
当OBEX 或者 TinyTP 连接建立后,server当前的文件夹是它的root目录。按照这种方式设备可以在root目录存取数据,而不需要要求client首先发送SETPATH请求。
3.3.6.1 Flags
The flags have the following meanings:
bit | Meaning |
---|---|
0 | backup a level before applying name (equivalent to ../ on many systems) 去当前目录的上一级目录 |
1 | Don’t create folder if it does not exist, return an error instead.如果path是server上存在的,则部创建此path,并返回错误。 |
2 | Reserved 保留 |
3 | Reserved 保留 |
4 | Reserved 保留 |
5 | Reserved 保留 |
6 | Reserved 保留 |
7 | Reserved 保留 |
The unused flag bits must be set to zero by sender and ignored by receiver. Refer to section 3.3.3.6 for a
description of how to delete folders.
保留bit必须设置为0,且server端要忽略它们。
3.3.6.2 Constants
The constants(常量) byte is entirely reserved at this time, and must be set to zero by sender and ignored by receiver.
常量的8个bit全是保留,client必须设置它们为0,server必须忽略它们。
3.3.6.3 Name header
Allowable values for the Name header are:
name header的允许值如下:
-
<name> - go down one level into this folder name, relative to the current folder
去当前目录的下的<name>文件夹。
-
<empty> - reset to the default folder
重新回到初始目录。
In addition, the Name header may be omitted when flags or constants indicate the entire operation being
requested (for example, back up one level, equivalent to “cd ..” on some systems.
name header也可能被忽略。由于flags也可以指定去上一级的目录。
The receiving side starts out in a root folder. When sending a folder, the client will start by sending a
SETPATH request containing the name of the folder. For example, if the full path for the folder on a PC is
C:\notes, the client will send “notes” as the Name header of a SETPATH operation. A PC server would
create or switch to the “notes” folder relative to the root folder (or perhaps(也许) create a mangled name if “notes” already exists and that was the preferred(首选的) behavior). As(当) subfolders of “notes” are encountered(遇到) by the sending routine, additional SETPATH requests with the subfolder names will be sent. As(当) folders are completed (all objects in the folder sent), the client will send a SETPATH (generally with no Name header) and the “back up a level” flag set.
当发送一个文件夹时,client会先发送SETPATH请求。举例:如果pc下的一个完整路径是c:\notes,则client会发送SETPATH请求,请求的name header的值是"notes"。pc server可能会在当前目录创建这个文件夹或者进入这个文件夹(已经存在)。当文件夹里的内容都被传输完毕后,client会发送一个SETPATH请求(通常没有name header),并设置flag的bit 0,告诉server,你可以返回到上一级目录了。
3.3.7 Session
The method proposed to(建议) add new session commands is to create one new OBEX command called
SESSION. The SESSION request is formatted as follows:
建议添加新的session command的方法是创建一个新的OBEX command(叫做SESSION)。
Byte 0 | Bytes 1, 2 | Bytes 3 to n |
---|---|---|
0x87 (Final bit set) | packet length | Sequence of headers. Session-Parameters must be the first header in the sequence |
The positive response to a SESSION request is 0xA0 (Success, with the high bit set. Any failure
response code can be used to indicate a negative response. Certain types(某些类型) of failures and the
corresponding(相应的) failure codes are described in the sections corresponding to(对应于) each session command. The format of the response is as follows:
成功返回0xA0,其余都是失败。失败的code的含义,后续说明。
Byte 0 | Bytes 1, 2 | Bytes 3 to n |
---|---|---|
response code | Response packet length | Optional sequence of response headers. If the Session-Parameters is used it must be the first header in the sequence |
3.3.7.1 CREATESESSION
The CREATESESSION command is sent by the Client to create a new session. This command must
include a Session-Parameters header containing the Session Opcode, Device Address and Nonce
fields. Optionally, a Timeout field can be included. The successful response to CREATESESSION is
0xA0 (Success, with the high bit set) in the response code followed by a Session-Parameters header
containing Device Address, Nonce, and Session ID fields. Optionally, a Timeout field can be included.
The client should verify that it creates the same session ID as sent by the server. If the Session ID does
not match then the client should close the session by using the CLOSESESSION command otherwise
the session is considered active.
CREATESESSION 由client发送,用来创建一个新的session。request里必须包括Session-Parameters header,header的值必须包含session opcode,设备地址,随机数字段。header的值里也可以包含timeout字段。针对CREATESESSION请求的响应里的header里,必须有Session-Parameters header,header的值必须包含设备地址,随机数字段,和Session ID字段。也可以包含timeout字段。client会校验server返回的session id和自己创建的session id是否相同,如果不相同,则发送CLOSESESSION 请求以关闭session;如果相同session则创建成功,并处于活跃状态。
The CREATESESSION command and response must fit in a single OBEX packet of size 255 bytes
(default maximum size) and have their Final bits set.
CREATESESSION 请求和响应都必须放在一个255 字节的OBEX packet里,而且还有设置final bit。
Only one session can be in the active state per transport connection. If a reliable session is already active
a second request should be rejected using the 0xC3 (Forbidden) response. To switch sessions the
current session must first be suspended. A server is not required to maintain multiple sessions at the
same time. All servers will have some maximum number of suspended sessions they can maintain. At
some point a server will receive a CREATESESSION request that will exceed(超过) this maximum number.
The server can either reject the new request or close an existing session and accept the new request.
The correct response depends on how long the existing sessions have been suspended(挂起). The server may want to prompt(提醒) the user if it cannot decide on its own. A proposal(建议) for an algorithm(算法) is given in the next paragraph. If a CREATESESSION request is rejected because the maximum number of sessions already exists then the proper response is 0xD3 (Service Unavailable).
在每个连接上,只能有一个处于活跃状态的session。如果已经有一个处于活跃状态的session了的话,再次创建session时,server会返回0xC3.切换活跃session前,要把当前活跃的session暂停。server没有必要维护多个session在同一时间。所有的server都有一个可以维护的session数量的最大值。在某个时间点,一个server接收到一个CREATESESSION 请求,如果处理这个请求则超过了可维护的session的最大数量。这时,server有2个选择,决绝这个请求,或者关闭一个存在的session并处理这个CREATESESSION 请求。能否正确的响应取决于session挂起了多久。如果user无法判断应该挂起多久,server可以提示。下面会介绍一个算法来提供建议的挂起时间。如果超过了可维护的session最大数量,server拒绝后,会返回0xD3 (Service Unavailable).
When a server receives a CREATESESSION request that exceeds the maximum number of sessions
supported the following algorithm can be used.
当超过最大可维护数量,可以使用下面的算法。
- Keep all suspended sessions with infinite(非常大的) timeouts on a sorted list by time suspended. The session with the longest time is at the front of the list.
根据设定的timeout时间长度,把已经挂起的session存放到一个list里。timeout时间最长的sessoin放在第一个位置。
-
Sessions with timeouts less then infinite should not be closed until the timeout occurs.
timeout时间到期前不应该关闭session
-
When a CREATESESSION request occurs exceeding the maximum number of sessions, the server
should check the suspended session list. If the list is not empty the first session on the list is
removed. This session is closed and its resources are used for the new session. If the list is empty
the incoming CREATESESSION request is rejected.
当超过最大可维护数量后,server去检查session list。如果这个list不是空的,则把list里的第一个session删除,并关闭从list里删除的session的连接,然后接收新的连接请求。如果list是空,则拒绝新来的CREATESESSION request 。
3.3.7.2 CLOSESESSION
CLOSESESSION is used to gracefully(优雅地) close an existing session. This command must include a Session-Parameters header containing the Session Opcode and Session ID fields. The value of the Session ID field is the one sent by the server in the response to the CREATESESSION command corresponding to
the session being closed. The successful response to CLOSESESSION is 0xA0 (Success, with the high
bit set) in the response code. The CLOSESESSION command can be used to close the active session or
any suspended sessions. The CLOSESESSION command and response must fit in a single OBEX packet and have their Final bits set. The CLOSESESSION command cannot be rejected if the Session ID corresponds to a valid(有效的) session. If the Session ID does not correspond to a valid session then the proper response is 0xC3 (Forbidden). If the active session is closed the unreliable session becomes the active session.
CLOSESESSION 用于优雅的关闭session。request里必须包含Session-Parameters header,header里必须包含
Session Opcode 和Session ID。session id是由server返回的。CLOSESESSION如果成功,则返回0xA0(final bit被设置)。CLOSESESSION 既可以关闭处于活动状态的session,也可以关闭处于挂起状态的session。CLOSESESSION的请求和响应必须在一个OBEX packet里。CLOSESESSION 里的session id如果是有效的话,则server不可以拒绝次请求。如果session id是非法的,则server返回0xC3.如果活跃的session被关闭了,则不可靠的session要变成活跃的session。
3.3.7.3 SUSPENDSESSION
SUSPENDSESSION is used to gracefully suspend the active session. This command must include a
Session-Parameters header containing the Session Opcode field. Optionally, a Timeout field can be
included. The successful response to SUSPENDESESSION is 0xA0 (Success, with the high bit set) in
the response code. Optionally, a Timeout field can be included.
The SUSPENDSESSION command and response must fit in a single OBEX packet and have their Final
bits set.
The SUSPENDSESSION command cannot be rejected if a reliable session is active. If the unreliable session is the current active session then the proper response is 0xC3 (Forbidden). The unreliable session becomes the active session when a reliable session is suspended.
SUSPENDSESSION 用于优雅地挂起活跃的session。request里必须包含Session-Parameters header,header里必须包含Session Opcode,timeout字段也可以包含在header里。成功返回0xA0.SUSPENDSESSION 的请求和响应必须在一个OBEX packet里。
如果可靠的session处于活跃状态,则server不可以拒绝SUSPENDSESSION 请求。如果当前活跃的session是不可靠的,则可能的返回值是0xC3。当可靠的活跃的session被挂起后,不可靠的session就变成活跃的session了。
3.3.7.4 RESUMESESSION
RESUMESESSION is used to resume(重新开始) a session that has been suspended. A session is suspended by using the SUSPENDSESSION command or when the underlying transport is broken. This command must include a Session-Parameters header containing the Session Opcode, Device Address, Nonce, and Session ID and fields. Optionally, a Timeout field can be included. The Session ID corresponds to the session being resumed and is the value returned by the server in its response to the CREATESESSION
command. The Device Address and Nonce are the values originally(原来) used in the CREATESESSION
command. This is true even if the device address has changed or the session is being resumed over a
different transport. Matching a session requires that all values match not just the Session ID (Device
Address, Nonce and Session ID must match).
RESUMESESSION 用于恢复挂起的session。当收到SUSPENDSESSION 请求或者传输被打断是,活跃的session会被挂起。RESUMESESSION request里必须包括Session-Parameters header,header的值必须包含session opcode,设备地址,随机数字段,session id。header的值里也可以包含timeout字段。要被恢复的session id,是由server返回的,是在CREATESESSION是创建的。设备地址,随机数是CREATESESSION请求里的使用的值。为了精确找到要恢复的session,session id,设备地址,随机数都必须一样。
The successful response to RESUMESESSION is 0xA0 (Success, with the high bit set) in the response
code. A Session-Parameters header containing Device Address, Nonce, Session ID and Next
Sequence Number fields must be sent. A Timeout field is optional. If the Device Address, Nonce and
Session ID do not correspond to a valid session then 0xD3 (Service Unavailable) should be returned. If
the information returned by the server does not match then the client should disconnect from the server.
CLOSESESSION should not be used since this could be a valid session for another device.
成功返回0xA0。返回的paekct里包含设备地址,随机数,session id和 Next Sequence Number。也可能包含timeout。如果client发过来的Device Address, Nonce and Session ID和要被恢复的session不匹配,则返回0xD3.client要断开连接
The RESUMESESSION command and response must fit in a single OBEX packet and have their Final
bits set.
RESUMESESSION 的请求和响应必须在一个OBEX packet里。
If the session is resumed successfully then the client must determine if a packet should be retransmitted(重新传输).If the session was suspended gracefully then no packets need to be retransmitted otherwise the client must follow the algorithm below:
如果session被成功恢复。client必须判断是否要重新传输一个packet。如果session是被优雅地挂起的话,就不需要重新传输,否则client要遵循下面的算法:
If the Next Sequence Number field equals the sequence number of the last
packet sent then
如果server返回的Next Sequence Number和client发送的最后一个packet的number相当则重新发送last packet
{
Re-Send last packet
} else if the Next Sequence Number field equals the sequence number of the
next packet to send then
如果server返回的Next Sequence Number和client要发送的next paekct的number相当,则继续判读别的条件
{
If the response to the last packet was not received then
如果client没有收到last packet的response,则重新发送last packet的所有header,除了Session-Sequence-Number header
{
Re-Send last packet minus all headers except Session-Sequence-Number;
} else {
Send next packet;
}
} else {
/* Sequence number is invalid */
断开连接
Disconnect underlying transport connection to OBEX server;
}
The server sets the Next-Sequence Number field in the RESUMESESSION response to the sequence
number of the next OBEX packet it expects to receive. The server must behave according to the
algorithm below upon(在。。。之上) receipt of the first request packet from the client after resuming the session.
server会在RESUMESESSION response里设置它要接收的下一个sequence number。server恢复了session后必须根据client发过来的第一个request packet,运用下面的算法来决定如果处理。
If the sequence number of the request is equal to the (Next Sequence Number
field minus one) mod 256 then {
/* The client did not receive the previous response */
Re-send the previous response;
Ignore the contents of the request since it was received properly
before the link was suspended;
} else if the sequence number of the request is equal to the Next Sequence
Number field then {
/* This is the next packet */
Process the packet;
Send the proper response;
} else {
/* The sequence number is invalid */
Send an Abort;
}
3.3.7.5 SETTIMEOUT
The SETTIMEOUT command is used to negotiate(协商) a new timeout specifying the number of seconds a session should be maintained while the session is suspended. This command must include a Session-
Parameters header containing the Session Opcode field. Optionally, a Timeout field can be included. If
the Session-Parameters header does not contain the Timeout field, the request is for an infinite(无限的) timeout. The successful response to SETTIMEOUT is 0xA0 (Success, with the high bit set) in the response code. A Session-Parameters field may be sent with a Timeout field. The lowest value for the timeout is the
value used by both sides. This command can only be used to change the timeout of the active
connection. If the active connection is the unreliable connection then 0xC3 (Forbidden) is the proper
response code.
SETTIMEOUT用于client和server之间协商出,session可以挂起多少秒。必须包含Session-Parameters header,而且header里要有Session Opcode字段。header里也可以有timeout字段。如果没有包含timeout字段,则timeout时间是无限的。成功返回0xA0。timeout的协商值,取client和server的最小值。SETTIMEOUT操作只能改变活跃的连接的timeout值,如果活跃的连接是非可靠的话,则server返回0xC3.
The SETTIMEOUT command and response must fit in a single OBEX packet and have their Final bits set.
SETTIMEOUT的request和response必须放在一个OBEX packet里,而且要设置final bit。
3.3.7.6 Generating a Session ID
The purpose of the Session ID is to uniquely identify the session. The Session ID is used when closing and resuming sessions. Both the client and the server want to be certain(确定无疑:to be certain) that the remote device is referring to the same session when issuing commands, especially when resuming a suspended session.
session id的作用是session的唯一标识。当要关闭和恢复一个session时,要使用session id。不管是client还是server都要必须确定对端的设备是在和自己使用同一个session,尤其是在恢复一个session的时候。
Both the client and the server provide information used to generate the Session ID. This helps to make certain(确定) that the Session ID is unique. Each device provides two pieces of information. The first is its Device Address. In the case of IrDA this is the 32-bit device address, which is not guaranteed(放心的) to be unique. The second is a Nonce, which must be unique for the given device. Given that(鉴于) the Nonce is unique as far as(只要) each device is concerned and that the device addresses are reasonably(尚可)unique (even in the case of IrDA) the resulting Session ID has a high probability of being unique.
client和server需要提供2部分信息,来帮助生成session id。第一部分是设备的地址,如果是红外设备这是32bit的地址,这32位的地址有可能有重复,所有还需要,第二部分的信息。第二部分是随机数,每个设备的随机数必须是唯一的。鉴于,只要设备是连接的,则随机数肯定是唯一的;而且设备地址唯一的可能性也尚可。用这2部分信息生成的session id基本就是唯一的了。
The Session ID is generated by applying(应用) the MD5 algorithm to the string created by concatenating(串联) the Client Device Address, Client Nonce, Server Device Address and Server Nonce. The reason for applying an algorithm such as MD5 is so that the size of Session IDs is fixed (16 bytes).
根据client的设备地址,随机数,server的设备地址,随机数,使用MD5算法,生成一个16字节的session id。
Device Addresses and Nonces can very in size so the MD5 algorithm is used to produce a 16-byte quantity. The MD5 algorithm was designed to produce a unique number given a string or file. MD5 was chosen since it is used in the OBEX authentication procedure and was very likely to already be present in an OBEX implementation.
之所以选择MD5,它已经用于OBEX authentication 了,而且有可能已经出现在OBEX实现代码了。
3.3.7.7 Negotiating(协商) Timeouts
All commands except CLOSESESSION involve(涉及) timeout negotiation. Timeout negotiation is simple. Each time a Session Command exchange occurs (except CLOSESESSION) both sides take the smallest timeout values sent and use that as the new timeout for the session. If a timeout value is not explicitly(明确的) sent it is assumed(假设) that the device is requesting an infinite(无限的) timeout.
除了CLOSESESSION以为,所有的session操作都涉及到了timeout时间。client和server的timeout协商是很简单的。每次session操作时(CLOSESESSION除外),双方都将发送的最小超时值作为会话的新超时值。如果timeout没有被发送,则说明希望永远不会超时。
3.4 Packet Timeouts
OBEX does not impose(施加) any timeouts between OBEX packets. Deciding whether to continue or cancel a session is normally left to user control, since(因为) waiting for user action is often what creates long periods between packets. In devices with reasonable user interface capabilities, timeouts are not recommended. However this specification(规范) does not prohibit(禁止) the use of timeouts. Some devices may find timeouts useful or even necessary, particularly(特别地) when sufficient(大量的) user interface to understand and/or control the reason for delay is not available.
在OBEX packet传输之间不加超时控制。通常要由用户来决定是继续还是取消是session,因为当等待用户点某个按钮等操作时,需要等待很长时间,而且是不定的。如果是有用户操作的功能,一般不使用超时功能。然而规范没有禁止使用超时控制功能。有些设备可能会发现超时是有用的,甚至是必要的,特别是当没有足够的用户界面来理解和/或控制延迟的原因时。
3.5 Authentication Procedure
The OBEX authentication procedure is based on two OBEX headers, the Authenticate Challenge and
Authenticate Response headers. It is assumed that the client and the server both share a secret such
as a password or pin number. This value is not sent over OBEX during the authentication process.
OBEX身份认证流程是基于2个header,一个是Authenticate Challenge一个是Authenticate Response。client和server都会分享一个密钥,可以是一个密码,也可以是pin number。在身份验证流程中不会通过OBEX发送这个值。
The client authenticates the server by sending an OBEX command with an Authenticate Challenge
header. This header will contain the digest-challenge, which is described later. To be authenticated, the
server’s response packet must contain the SUCCESS response code and an Authenticate Response
header. The content of the Authenticate Response header contains the digest-response string, which is
described later. The client verifies(校验) the server by generating(生成) its own request-digest string and comparing it to the one sent as part of the digest-response. If the server is not authenticated the client can simply disconnect from the server.
client通过发送Authenticate Challenge header来验证server。header里包含digest-challenge。server必须返回成功的response而且包含Authenticate Response header。Authenticate Response header里包含digest-response字符串。client自己生成 request-digest字符串,然后用 request-digest和server返回的digest-response里面的request-digest做比较。如果认证不成功,client可以断开和server的连接。
The server authenticates the client using the same basic algorithm. When a client attempts(尝试) an operation to the server which requires authentication, the server sends an Authenticate Challenge header along with an UNAUTHORIZED response code in a response packet. When the client receives this response, it must re-send the command packet with an Authenticate Response header. The server verifies the client
by generating its own request-digest and comparing it to the one sent in the digest-response by the client.
If they are the same, the client is authenticated. If the client is not authenticated, the server will simply
respond to all operations, including the current one, with the UNAUTHORIZED response code.
server校验client的做法,和client校验server是一样的。当client个server发了一个请求,但server要校验client是否有权限请求,则server要给client的response的里面的response code必须是UNAUTHORIZED ,而且response还要有Authenticate Challenge header 。当client接收到此response后,它必须要再发一次请求,而且要包含Authenticate Response header。server为了校验client,首先自己先生成一个request-digest,然后和client发过来的digest-response做比较。如果它们相同,验证OK,如果NG,则server返回的response的response code全是UNAUTHORIZED。
The algorithm used by the client to authenticate a server is straightforward(直截了当的). The client will normally authenticate the server as part of the OBEX CONNECT procedure. The server can authenticate the client for any operation including the CONNECT operation and individual PUT and GET operations.
client验证server是算法是直截了当的。client可以再CONNECT的操作里顺道就验证server了。server可以验证client的任何操作,比如CONNECT,PUG,GET。
When the server authenticates the client for an OBEX connection the server will send the Authenticate Challenge header in the response to the CONNECT command with a response code of UNAUTHORIZED. When the client receives a response to the CONNECT command containing an Authenticate Challenge
header and the UNAUTHORIZED response code, it should repeat the CONNECT command and include
an Authenticate Response header. If the original CONNECT command also contained an Authenticate Challenge and/or Target header, these headers must also be present in the second CONNECT command.
当server验证client发过来的CONNECT请求时,server会response一个Authenticate Challenge header,response code是UNAUTHORIZED。当client接到这个带有Authenticate Challenge header的response后,client要重新发送CONNECT请求,并且包含Authenticate Response header。如果client第一次发送的CONNECT里就包含了Authenticate Challenge and/or Target header的话,第二次发送CONNECT时,必须把这些headers带上。
When the server wants to authenticate an individual operation, it will reject the first attempt by the client
with an OBEX response containing the UNAUTHORIZED response code and an Authenticate
Challenge header. The client must retry the operation this time including an Authenticate Response
header. If every operation requires authentication then it probably makes sense(合理) to authenticate the CONNECT operation and not perform individual operation authentication.
当server要验证一个单独的operation时,它会先拒绝client的请求,返回UNAUTHORIZED 。然后client必须重新发送一次,并包含Authenticate Response header。如果每个操作都需要验证的话,比较合理的做法是在CONNECT的时候验证一次就好,而不是次次都验证。
Multiple Authenticate Challenge headers can be sent in one OBEX packet. This is done for a number of
reasons(这样做有很多原因):
OBEX packet可以包含多个Authenticate Challenge headers ,这么做是有很多原因的:
-
In the future, there may be different types of challenge algorithms or hashing functions used. Each
challenge will represent(代表) a possible algorithm to use.未来可以使用各种不同的认证算法或哈希函数。每个challenge 代表一个可能的算法。
-
There may be different passwords for full access versus(与。。。相比) read only access. Two headers are used, one for each access method.
有的验证可能分只读权限和全部权限,只读权限的信息在一个Authenticate Challenge header,全部权限的信息在另一个Authenticate Challenge header。
When more than one Authenticate Challenge header exists in an OBEX packet, the nonce must be
different for each one. Devices are not required to deal with multiple Authenticate Challenge headers so
some devices may only process the first one. Therefore, it is important that the most general or common
challenge be sent in the first header.
当OBEX packet里包含多个Authenticate Challenge header是,nonce 字段必须是不同的。有的设备不能处理多个Authenticate Challenge header,所以一些设备只能处理第一个Authenticate Challenge header。因此,共通的challenge header要放在第一个header处。
When multiple Authenticate Challenge headers are sent, the sender will use the nonce in the digest-response to determine which nonce to use when generating the request-digest. If a nonce does not exist in the digest-response then the nonce sent in the first Authenticate Challenge header is used.
当发送方发送了多个Authenticate Challenge header后,发送方会使用接收方返回的digest-response,来决定使用哪个nouce生成request-digest。如果返回的digest-response里面不包含nonce,发送方使用自己发送的Authenticate Challenge header里面的第一个nonce。
3.5.1 Digest Challenge
The OBEX digest-challenge is a simplified(简易) version of the HTTP digest-challenge. One of the limitations(限制) of OBEX is that the response to a PUT or CONNECT command must fit in a single OBEX packet.
OBEX digest-challenge是HTTP digest-challenge的简易版本。它的限制是,PUT or CONNECT的response必须在一个OBEX packet里。
Some devices only support a maximum size OBEX packet of 255 bytes so this limits the amount of data that
can fit in a response and therefore, limits the size of the digest-challenge and digest-response.
一些设备支持的最大OBEX packet是255字节。所以可以传输的data的大小就受到了限制。因此要限制 digest-challenge 和 digest-response的大小。
The HTTP challenge contains a number of fields including a string that identifies the challenge as basic or
digest. Within a digest challenge the digest-challenge can specify the hashing algorithm to use, the realm(领域),the domain, a nonce, and option fields.
HTTP challenge里包含一些字段,有一个是string,它作为challenge 的基本和摘要。在digest challenge里digest-challenge可以指定哈希算法,使用realm,domain,nonce,别的可选字段。
The main element is the nonce. The nonce is the random string, which is combined with(联合) the secret to produce the main portion(部分) of the digest-response.
nonce是一个随机的字符串,用nonce加上secret来做出digest-response的主要部分。
The OBEX authentication algorithm needs to be simple yet flexible. The minimal challenge should only contain a nonce but there may be cases where a userid/username is needed to determine which password to use.
OBEX认证算法需要简单而灵活。最小的challenge只需要nonce,但在某些情况下,也需要userid/username来决定使用哪个密码。
Some OBEX servers may support multiple different users each with their own passwords. Therefore, the
server must be able tell the client that a userid is needed. The default hashing function in HTTP is MD5 and OBEX will use this algorithm. In the future, other algorithms may be introduced but at this time, only MD5 is supported.
一些OBEX server支持不同的用户使用不同的密码。因此server必须告诉client,它需要一个userid。HTTP默认的哈希算法是使用MD5,OBEX也使用MD5.未来也会支持别的算法。
The OBEX digest-challenge string can contain multiple fields. The HTTP digest-challenge is based on
ASCII strings. To keep the size small, the OBEX digest-challenge will use a tag-length-value encoding
scheme. Both the tag and value length fields, are one byte in length. The table below shows the OBEX
digest-challenge fields.
OBEX digest-challenge string 可以包含多个字段。HTTP的digest-challenge使用ASCII字符串。由于OBEX packet的空间有限,所以使用tag-length-value编码方案。tag和value的length都占一个字节。下表展示了digest-challenge 字段。
Tag | Name | Value Len | Value Description | Default Value |
---|---|---|---|---|
0x00 | Nonce | 16 | String of bytes representing the nonce | |
0x01 | Options | 1 | Optional Challenge Information | 0 |
0x02 | Realm | n | A displayable string indicating which userid and/or password to use. The first byte of the string is the character set to use. The character set uses the same values as those defined in IrLMP for the nickname.是一个字符串用来指定使用哪个userid和密码。字符串的第一个字节是要使用的字符集。字符集的名字与IrLMP定义的相同。 |
Each field is described in more detail below.
3.5.1.1 Nonce
The nonce is required. It is important that the nonce be different each time it is sent. An example nonce,
based on the example given in the HTTP authentication document, is as follows:
- H(time-stamp “:” private-key)
Where time-stamp is a sender-generated time or other non-repeating value and private-key is data known
only to the sender. The MD5 hashing algorithm is applied to the time-stamp string to produce a 128 bit
(16 byte) binary string. This resulting string is the nonce.
nonce是必须字段。nonce必须是唯一的。HTTP用下面的方式做成nonce。
- H(时间戳":"私有key)
time-stamp是发送方生成的时间和别的不重复的值,再加上私有key,这个key只要发送方直到。用time-stamp作为MD5算法的参数,运算生成一个128bit(16个字节)的字符串。这个字符串就是nonce。
3.5.1.2 Options
The option field is optional. If an option field is not sent the assumed(假定) value for it is 0. Two options are defined. The first controls the sending of a userid. If this option is set then the entity receiving the
challenge must respond with a userid in the digest response string. The second option indicates the
access mode being offered by the sender of the challenge. The two access modes are full access (both
read and write) and read only.
可选字段如果没有设置,则默认全为0。8个bit位,其中只要2个被定义了,其余都是保留。当第一个bit位被设定后,接收方返回的digest response里面必须包含userid 。当第二个bit位是权限位,0:只读权限,1:读写权限。
bit | Meaning |
---|---|
0 | When set, the User Id must be sent in the authenticate response. |
1 | Access mode: Read Only when set, otherwise Full access is permitted. |
2 | Reserved 保留 |
3 | Reserved 保留 |
4 | Reserved 保留 |
5 | Reserved 保留 |
6 | Reserved 保留 |
7 | Reserved 保留 |
The unused options bits must be set to zero by sender and ignored by receiver.
没有使用的bit必须设置为0,而且接收方必须忽略这些位。
3.5.1.3 Realm
The realm field is optional. The realm is intended(打算) to be displayed to users so they know which userid and password to use. The first byte of the string is the character set of the string. The table below shows the different values for character set.
realm是可选字段。使用realm来告诉user,他们应该使用哪个userid和密码。第一个字节是后面字符串的字符集的名字。
Char Set Code | Meaning |
---|---|
0 | ASCII |
1 | SO-8859-1 |
2 | SO-8859-2 |
3 | SO-8859-3 |
4 | SO-8859-4 |
5 | SO-8859-5 |
6 | SO-8859-6 |
7 | SO-8859-7 |
8 | SO-8859-8 |
9 | SO-8859-9 |
0xFF = 255 | UNICODE |
3.5.2 Digest Response
The digest-response string can contain multiple fields and uses a tag-length-value encoding scheme. The
digest-response fields are shown below.
digest-response 字符串包含多个字段,使用tag-length-value编码方案。digest-response字段的解释如下:
Tag | Name | Value Len | Value Description | Default Value |
---|---|---|---|---|
0x00 | Request-digest | 16 | String of bytes representing the request digest。返回给对方的request-digest,对方先自己生成一个request-digest,然后和这个request-digest比较,如果相等则认证OK。 | |
0x01 | User Id | n | User ID string of length n. Max size is 20 bytes | |
0x02 | Nonce | 16 | The nonce sent in the digest challenge string.对方发过来的nonce,原封不动的发回去。 |
Each field is described in more detail below.
3.5.2.1 Request-digest
The request-digest is required and is calculated as follows:
H(nonce ":" password)
The nonce is the string sent in the digest-challenge. The password is the secret known by both the client
and server. The MD5 hashing function is applied to the nonce/password string to produce a 128-bit (16
byte) string. This resulting string is the request-digest。
request-digest是必须字段,是H(nonce ":" password)。
nonce是对方发过来的。password是client和server都知道的secret。MD5使用nonce和password生成128bit(16字节)的字符串。
3.5.2.2 Userid
The userid is required if the digest-challenge contains an options field with the userid bit set to 1. The
userid is used to identify the proper(正确的) password.
当digest-challenge的option字段的userid bit位被设置位1,则userid字段是必须字段。userid返回给对方,对方根据返回的userid,得到正确的密码。
3.5.2.3 Nonce
The nonce is optional. When multiple Authenticate Challenge headers are sent, the nonce is used to
indicate to which header the request-digest is responding. The nonce is the same value as sent in the
digest-challenge. If a nonce is not sent in the digest-response then it is assumed that the digest-response
is a response to the first Authenticate Challenge header. This allows devices that do not parse multiple
Authenticate Challenge headers to work with devices that send multiple headers.
nonce是可选的。当发送过来多个Authenticate Challenge header时,nonce 用来告诉对端,这个Digest Response是对应你发过来的哪个Digest Challenge。接收方把接收到的nonce,原封不动的发回去。如果没有发回nonce,server就是告诉client,我回的Digest Response是对应你发的第一个Digest Challenge。有了这个特性,接收方设备就可以不需要解析多个Authenticate Challenge headers,也可以和发送多个Authenticate Challenge headers 的设备通信。
3.5.3 Hashing Function
The default hashing function used in OBEX is MD5. The following paragraph briefly describes the MD5
algorithm. Refer to RFC 1321 at http://info.internet.isi.edu:80/in-notes/rfc/files/rfc1321.txt for more
detailed information, including example source code. Additional MD5 source code can be found in
Appendix 12.5 MD5 Algorithm for Authentication at the end of this specification.
默认的哈希算法是MD5.后续的章节详细的描述的MD5算法。可以参考RFC 1321.另外MD5的代码可以在附录12.5里找到。
The MD5 algorithm takes as input a message of arbitrary(任意) length and produces as output a 128-bit
"fingerprint" or "message digest" of the input. It is conjectured(推测) that it is computationally(计算地) infeasible(不可行) to produce two messages having the same message digest, or to produce any message having a given prespecified target message digest. The MD5 algorithm is intended for digital signature applications,where a large file must be "compressed" in a secure manner before being encrypted with a private (secret) key under a public-key cryptosystem such as RSA.
The MD5 algorithm is designed to be quite fast on 32-bit machines. In addition, the MD5 algorithm does
not require any large substitution tables; the algorithm can be coded quite compactly.
MD5算法:能根据任意长度的信息,来生成一个128bit的。只要入力信息相同,生成的128bit的窜就相同。
3.5.4 Authentication Examples
Example 1: Client and Server Connection Authentication (no userid)
为使用userid的例子。
-
第一个request:
client发送CONNECT请求,带Authenticate challenge header和target header。Authenticate challenge header里包含nonce和optional,optional里没有设置userid和权限位。
-
第一个response:
server接收到了CONNECT请求。由于是CONNECT请求,server端也需要发送Authenticate challenge header。Authenticate challenge header里包含nonce和optional,optional里没有设置userid和权限位。
-
第二个request:
client接收到了server的Authenticate challenge header,client把第一次request的header,再加上 Authenticate response header。
-
第二个response:
server返回Authenticate response header,Connection ID header,who header(值为Target header的值)
Example 2: Server Authenticates Get operation (userid required)
使用userid的例子。
-
第一个request:
client请求一个对象,使用的name header
-
第一个response:
server需要验证client的身份,所以发了一个Authenticate challenge header,并且设置了userid bit位。
-
第二个request:
client发现server发来一个Authenticate challenge header,并且设置了userid bit位,所以回了一个Authenticate response,里面有userid。
-
第二个response:
server收到了userid,并验证发现没有问题,则返回client所请求的object。
3.6 Multiplexing with OBEX
It is sometimes necessary for different clients to perform operations in a manner that appears to the user
to be simultaneous(同时发生的). In addition, some connections may be very long lived while(但是) others come and go quickly. This creates the need for a mechanism(机制) that allows multiple clients to access OBEX services concurrently(并发). The following sections cover two methods recommended(推荐) for multiplexing(多路复用) commands over OBEX. The first method is geared toward(适用于) use with applications that run under the umbrella(雨伞) of the default OBEX server.
3.6.1 Connections multiplexed at the OBEX Command level
The OBEX protocol layer provides this form of multiplexing. Multiple OBEX connections (using the
Connection Id header) are allowed at one time but only one command can be executed at a given time.
This type of multiplexing only requires one OBEX parser because the multiplexing occurs above the
parser. This type of multiplexing is necessary because most services are accessed through the default
OBEX server and hence over a single transport connection.
OBEX协议层提供一种多路复用的格式,如图3.6.1.使用connect id的多个OBEX 连接,在同一个时刻是被允许的,但是只有一个command可以被执行。这种形式的多路复用只需要一个OBEX解析器。这种形式的多路复用是实际可用的,因为大多数的service是通过default OBEX server来访问的,而且只需要一个connection。
3.6.2 Connections multiplexed at the OBEX Transport layer
This type of multiplexing is external(外部的) to OBEX and relies(依赖) on the multiplexing capabilities of the underlying transport layer. Multiple OBEX servers exist, one for each different application. In turn(轮流的) each of these OBEX servers may themselves offer the connection and multiplexing types described above. In IrDA for example, the LM-MUX provides this form of multiplexing. Multiplexing at the transport layer is most useful when neither side of the application are constrained(被限制) or limited by resources. It also allows for a finer grained multiplexing which may be important for some applications.
这种形式的多路复用是外部提供的,所以依赖传输层。所以有多个OBEX server,每个server服务不同的application。他们(server是)轮流地提供连接。