欢迎关注公众号: nullobject 。
文章首发在个人博客 https://www.nullobject.cn,公众号nullobject同步更新。
这篇文章主要为PTPIP的学习笔记
本文档由nullobject对应PTP-IP标准协议1.0版本进行学习整理,原版协议为英文版,学习时依靠自己理解和使用有道云翻译,对理解不到位、翻译有问题的地方麻烦批评指正。—— by nullobject in 2019-06-03 15:29
本文档描述了一个基于IP网络的ISO-15740/PIMA 1574:2000/图片传输协议(PTP)的实现。
PTP被设计用来提供与数字静止摄影设备的标准通信。该协议指定了标准的图像引用行为、操作、响应、事件、设备属性、数据集和数据格式,以确保互操作性,还提供了可选的操作和格式,以及扩展机制。
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, “OPTIONAL” in this document are to be interpreted as described in “Key words for use in RFCs to Indicate Requirement Levels”[5].
下表列举了本文档的参考资料:
ID/Description |
---|
[1] PTP protocol, PIMA 15740:2000 |
[2] Computer Networks, Andrew S. Tanenbaum, ISBN:0130661023, Prentice Hall Aug 09,2002 |
[3] UPnP Standard, http://www.upnp.org/resources/documents.asp |
[4] ZeroConf Standard, http://www.zeroconf.org |
[5] Formatting Conventions. http://www.faqs.org/rfcs/rfc21129.html |
缩写 | 含义 |
---|---|
TCP | Transfer Control Protocol |
UDP | User Datagram Protocol |
IP | Internet Procotol |
PnP | Plug and Play |
PTP | Picture Transfer Protocol |
PTP-IP | IP Picture Transfer Protocol |
PIMA | Photographic and Imaging Manufacture Association |
DHCP | Dynamic Host Configuration Protocol |
v4LL | IPv4 Link-Local Address |
Petronel Bigioi – FotoNation Ireland
George Susanu – FotoNation Ireland
Alexei Pososin – FotoNation Ireland
Denis McHugh – FotoNation Ireland
Eran Steinberg – FotoNation US
Yury Prilusky – FotoNation US
PTP规范定义了设备角色、操作、图像格式和其他相机特定的数据类型和结构。在PTP的TCP/IP实现中,所有术语和定义都按照PTP规范中定义的那样使用。
从通信的角度来看,设备可以充当启动器设备(Initiator)或响应端设备(Responder),启动器设备相当于一个客户端,响应端设备相当于服务端。启动器设备是向响应端设备发起操作请求的设备。响应端设备则是能够响应这些操作请求的设备。一个设备可能只是一个启动器设备,或者只是一个响应端设备,或者两者兼备,但不能在同一个设备连接上同时担任两种角色。
操作请求只能由启动器设备发起;事件被响应端设备用于把有关它状态的改变通知启动器设备。
根据PTP协议,会话被定义为两个设备之间的逻辑连接,操作和事件事务可以通过该逻辑连接进行通信。根据PTP规范,一个响应端设备可以支持多个并发会话,每个会话都有自己的状态。
当启动器设备请求OpenSession操作事务时将会打开一个会话,并且使用响应端设备发出的一个有效响应成功结束该请求。
会话将在启动器设备请求CloseSession操作事务时被关闭,并且使用响应端设备发出的一个有效响应成功结束该请求。当启动器设备和响应端设备之间的连接被关断开时会话也会被关闭(例如通信超时)。
大多数操作需要在一个开放会话上下文中执行。不过,不需要打开会话就可以通过GetDeviceInfo操作获取设备功能。
支持多会话的设备必须能够使它们彼此保持异步和不透明。
通常,如果使用相同传输级别的通信通道,则会话ID旨在使响应端设备能够按适当的顺序分发来自不同启动器设备的请求。对于打开不同通信通道的传输,对于每个会话,不需要重新设置会话ID,因为响应端设备将能够处理多个会话。
PTP的PTP- IP传输实现不会将会话ID发送到响应端设备。响应端设备可以通过控制它允许的最大PTP- IP连接数来限制并发PTP会话的数量。
如果启动器设备的PTP-IP层发现响应端设备不接受新的PTP-IP连接,它将向PTP层发送传输特定的错误代码。在建立传输指定连接之后,启动端设备可以向远程响应端设备发出GetDeviceInfo和OpenSession请求。在这个阶段中,响应端设备可能返回一个设备繁忙(Device_Busy)的PTP错误作为对OpenSession的响应(如果响应端设备对它能够支持的并发PTP会话的数量有限制)。在这种情况下,启动端设备应该释放PTP连接,并稍后重试。
事务是PTP协议中操作的基本单位,PTP协议规定的所有操作都基于事务进行。事务操作请求由启动器设备(Initiator)发起,传送到到响应端设备(Responder),在一个会话(Session)中,同一时间只能有一个事务操作在执行,操作事务在一个会话中默认是同步的。
一个事务通常由三个阶段组成:Operation Request、Operation Response、Data Phase,如下图:
取决于事务操作本身,Data Phase这一可选阶段可能不会存在于一个事务流程中,即事务只有Operation Request和Operation Response。而当事务中存在Data Phase时,数据可能从初始化器Initiator发送到响应设备Responder(即I–>R),或者反过来R–>I,但同一个操作中数据只能在一个方向上传输。
事务ID(TransactionID)用于在一个给定的会话中标识不同事务,与在PTP协议的第9.3.1项中定义的事务ID相同,是一个32位无符号整型数字。事务ID在给定的会话中是唯一且连续的数字序列,其范围从0x00000001到0xFFFFFFFE,0x00000000和0xFFFFFFFF作为保留值不被使用。
在PTP标准协议的**7[1]**节中,为底层传输层定义了这些需求。
PTP标准协议 7.1节:断开事件。PTP协议的这一节要求传输层必须向上层的报告设备断开。这是通过PTP-IP 层生成设备断开通知来实现的。
PTP标准协议 7.2节:稳定、无错误通道。PTP协议的这节要求需要可靠,无错误的通道。在PTP-IP中,这通过使用配置了Keep Alive选项的TCP连接来实现。
PTP标准协议 7.3节:异步事件的支持。PTP要求支持异步事件,在PTP-IP中,事件连接被定义为用于传输异步事件,并且与命令/数据通道是异步的。
PTP标准协议 7.4节:设备发现和枚举。PTP要求支持设备发现和枚举服务,在PTP-IP中,设备发现和枚举使用对IP网络可用的通用解决方案来实现,可以使用一个基于设备发现协议[5]的自定义UDP协议。
PTP标准协议 7.5节:传输特定。PTP要求图像设备传输的实现符合相关机构发布的特定使用传输规范。本文档说明了如何使用位于TCP/IP协议栈上层的PTP-IP传输。
在PTP-IP的实现中,用户程序与PTP-IP层之间的通信基于PTP事务模型实现,参考PTP协议的**9.3[1]**节,该通信模型如下图:
本文档的目的在于制定和说明PTP-IP通信协议,应用程序和PTP-IP层(编程接口,API)之间交互的实现并不在本文档的内容范围内。本文档仅以互操作性的方式规定两个PTP-IP实体之间的通信。不过,PTP层(用户应用程序)和PTP-IP层之间的接口可能由以下基本类型组成:
操作请求(Operation Request)
每当进行请求操作时,启动器设备(Initiator)中的应用程序就会发送一个操作请求,随即该请求被响应端设备(Responder)接受。操作请求中通常包含一组与该操作相关的参数。
操作响应(Operation Responses)
每当接收到一个操作请求,响应端设备(Responder)会发送一个操作响应作为该操作请求的回应。对于启动器设备(Initiator)中应用程序发起的每个操作请求,都需要回复一个操作响应。操作响应中总是会包含其对应的操作请求的结果代码,并且可能会包含一组参数。
数据读入(Data-In)
数据读入(Data-In)是相对于用于应用程序而言的,即数据流向是从响应端设备(Responder)到启动器设备(Initiator)。
数据写出(Data-Out)
数据写出(Data-Out)的数据流与数据读入(Data-In)相反。
事件(Events)
PTP-IP中的事件是指有关响应端设备(Responder)的状态变更的通知,事件由响应端设备启动。
设备连接/断开(Device Connect/Disconnect)
设备的连接/断开是平台相关类型的事件。这两个事件并不直接在启动器设备和响应端设备之间通信,而是当检测到设备被连接/断开时由各自的PTP-IP层生成。
操作和事件两种事务的类型的定义在PTP协议文档的10.11、**12 [1]节中可以找到,并且PTP协议在14 [1]**节中为设备标准的一致性确定了一组操作和事件。
PTP标准协议文档的**7 [1]**节定义了PTP标准传输需求,而PTP-IP则是基于使用TCP层作为传输层实现:
与PTP一样,PTP-IP也期望从其传输层获得可靠、稳定无错误的通信通道,而TCP(位于TCP/IP协议栈中)正是可以满足这些需求的自然传输层。TCP是一个基于流的传输层,它提供多个通信通道(TCP Connection)和无错误的数据传输。
在PTP-IP中,两个设备之间的所有通信都通过两个TCP连接(逻辑数据通道)进行:
由于事件本身具有异步性质,事件的数据包与操作/数据事务数据包分开分别通过两个单独的通道传输。
PTP-IP的 命令/数据连接用于传输PTP操作请求、响应和数据事务,以及特定于PTP-IP的数据包。该连接由启动器设备(Initiator)建立,并标志本地及响应端设备(Responder)的IP地址和端口号。响应端设备(Responder)的IP地址和端口号通常是通过设备发现机制来确定。
PTP-IP的事件连接作为启动器设备(Initiator)开启的与响应端设备(Responder)之间的第二个连接,用于传输PTP事件,以及特定于PTP-IP的数据包。与命令/数据连接相同,事件连接由启动器设备(Initiator)发起建立, 并标志本地和响应端设备(Responder)的IP地址和端口号,响应端设备(Responder)的IP地址和端口号通常是通过设备发现机制来确定。
在启动器设备(Initiator)与响应端设备(Responder)之间的通信中,每当需要这些传输通道时,启动器设备(Initiator)将负责发起与响应端设备(Responder)的PTP-IP/TCP连接。如前文所述,PTP-IP的传输通道使用TCP连接实现:一个通道用于命令/数据传输,另一个则用于事件传输。每个通道都会标志本地以及响应端设备(Responder)IP地址和端口号。从PTP-IP的通信模型中可以看到,启动器设备(Initiator)的PTP-IP实际上是一个TCP客户端,对应地响应端设备(Responder)的PTP-IP则是一个TCP服务器。响应端设备(Responder)轮询等待连接请求,并且预定义(或者动态分配)了一个TCP连接端口号.PTP-IP服务端默认端口号为15740。PTP-IP连接建立过程:
PTP-IP中的TCP连接应遵循上图所示顺序进行:
启动器设备(Initiator)发起命令/数据的TCP连接:指定响应端设备(Responder)的IP地址和端口号,并连接到响应端设备(Responder);
TCP连接建立成功后,启动器设备(Initiator)立即发送一个Init Command Request包,数据包中需要包含启动器设备(Initiator)的唯一标识(GUID和启动器设备的用户友好名称),例如:
响应端设备(Responder)程序根据实际情况,回复启动器设备一个Init Command Ack包以告知启动器设备请求成功并且可以继续进行连接;或者回复Init Fail数据包表示请求失败,以告知启动器设备请求访问被拒绝,并且断开命令/数据的TCP连接,同时启动器设备接收到请求失败的回应后也应该断开相应的的命令/数据连接。
启动器设备(Initiator)接收到Init Command Ack包后,继续发起一个事件的TCP连接:指定响应端设备(Responder)的IP地址和端口号,并连接到响应端设备(Responder)。注意该连接与第1步中的连接是区别开的。
一旦连接建立成功,启动器设备(Initiator)立即发送一个Init Event Request包,数据包需要包含第4步骤中接收到的连接号(Connection Number)。响应端设备(Responder)需要根据这个连接号将命令/数据和事件两个TCP连接关联同一个PTP-IP连接和同一个PTP会话。
与步骤3类似,请求成功则回复一个Init Event Ack包,在响应端设备(Responder)资源不足时,回复Init Fail包告知启动端请求失败。
一旦启动器设备(Initiator)接收到步骤6中回传的Init Event Ack包则认为请求成功,此时PTP-IP连接真正建立完成,接着即可进行进一步的数据通信。
在第二个TCP连接(事件连接)建立失败的情况下,第一个TCP连接(命令/数据连接)需要被关闭,稍后启动器设备(Initiator)应再次尝试建立PTP-IP连接。建议每次创建PTP-IP连接的时间间隔为30s。
根据PTP协议**7 [1]**节,PTP-IP层要求传输通道可靠、无错误。这种传输通道可以通过正确配置TCP连接来实现。
PTP-IP的TCP连接应该使用一下选项创建:
Keep Alive 选项:启动器和响应端需要同时需要同时开启这个选项,以确保两端的TCP实体在非活跃时期能够维持连接。开启这个选项后,启动器和响应端各自的TCP栈会通过TCP协议特定的方式来检查所配对的设备是否仍旧能够响应。这种检查方式是在TCP层进行,对上层的PTP-IP来说是透明的。
禁用Nagle算法:需要在启动器和响应端程序的TCP/IP协议栈上禁用Nagle算法,以避免在传输命令代码和响应时出现不必要的延迟。
总的来说就是需要设置如下选项(Qt为例):
// 禁用Nable算法
mTcpSocket->setSocketOption(QAbstractSocket::SocketOption::LowDelayOption,1);
// 开启Keep Alive选项
mTcpSocket->setSocketOption(QAbstractSocket::SocketOption::KeepAliveOption,1);
当不再需要PTP-IP时,由启动器设备(Initiator)关闭连接。当启动器设备(Initiator)或者响应端设备(Responder)在打开的传输通道上发生错误而导致这些通道不稳定时,也应关闭PTP-IP连接。关闭PTP-IP连接时两个TCP连接(命令/数据连接和事件连接)都必须要关闭。
本节主要介绍用于在启动器设备(Initiator)和响应端设备(Responder)间通信的一组数据包类型。PTP-IP的数据包类型相当于PTP协议中定义的操作请求(Operation Request)、响应(Response)、**数据(Data)和事件(Event)事务类型。PTP-IP数据包中的所有多字节值都使用小端(Little-Endian)**格式表示,通常一个PTP-IP数据包的格式如下:
Field | Size[Bytes] | Data Type |
---|---|---|
Length | 4 | UINT32 |
Packet Type | 4 | UINT32 |
Payload | 根据Length计算 | ? |
长度(Length):4字节,长度参数决定了包含包头在内的整个数据包的大小;
包类型(Packet Type):4字节,该字段标志了数据包的类型,该参数有下列可选的值:0x0000NNNN*表示隐藏值。
Value | Description |
---|---|
0x00000000 | 保留值 |
0x0000NNNN* | Init Command Request Packet |
0x0000NNNN* | Init Command Ack |
0x0000NNNN* | Init Event Request Packet |
0x0000NNNN* | Init Event Ack Packet |
0x0000NNNN* | Init Fail Packet |
0x0000NNNN* | Operaqion Request Packet |
0x0000NNNN* | Operation Response Packet |
0x0000NNNN* | Event Packet |
0x0000NNNN* | Start Data Packet |
0x0000NNNN* | Data Packet |
0x0000NNNN* | Cancel Packet |
0x0000NNNN* | End Data Packet |
0x0000NNNN* | Probe Request Packet |
0x0000NNNN* | Probe Response Packet |
0x0000NNNN* - 0xFFFFFFFF | 保留值 |
该数据包在命令/数据传输通道被建立后立即被启动器设备(Initiator)发送。该数据包通过命令/数据连接传输,用于通知响应端设备(Responder)对启动器进行标识,从而使响应端设备(Responder)能够实现过滤机制。数据包结构如下:
Field | Size[Bytes] | Data Type |
---|---|---|
Length | 4 | UINT32 |
Packet Type | 4 | UINT32 |
Initiator GUID | 16 | UINT8 |
Initiator Friendly Name | Variable | UINT16 |
Initiator Protocol Version | 4 | UINT32 |
- 启动器设备的GUID和响应端设备的GUID可用于进行设备绑定。若启动器设备的GUID的16个字节全由0xFF组成,则表示该启动器设备是一个匿名设备,此时由响应端设备决定是否允许连接。更多信息参考[附录5.3](#5.3 设备绑定和认证)。
- 启动器设备的用户友好名称是一个以**空(NULL)字符结尾的Unicode字符串。包括结尾的空字符,其最大长度位40个字节。不使用该字段时,必须使用一个空(NULL)**字符填充该字段。
数据包示例:
对应地:
该数据包由响应端设备(Responder)回传给启动器设备,以响应启动器设备发送的Init Command Request Packet,并为接下来的PTP-IP会话分配一个连接号(Connection Number),该数据包在命令/数据连接上传输。
包结构如下:
Field | Size[Bytes] | Data Type |
---|---|---|
Length | 4 | UINT32 |
Packet Type | 4 | UINT32 |
Connection Number | 4 | UINT32 |
Responder GUID | 16 | UINT6 |
Responder Friendly Name | Variable | UINT16 |
Responder Protocol Version | 4 | UINT32 |
- 响应端设备的用户友好名称是一个以**空(NULL)字符结尾的Unicode字符串。包括结尾的空字符,其最大长度位40个字节。不使用该字段时,必须使用一个空(NULL)**字符填充该字段。
- 连接号在启动器设备和响应端设备连接被建立的期间保持有效。一旦响应端设备成功关联属于同一个PTP-IP连接的两个TCP连接,连接号即可被重新使用。
实际该数据包结构看起来如下:
对应地:
命令/数据连接被成功建立后,该数据包被启动器设备发送至响应端设备用于建立事件连接。启动器设备在接收到一个有效的Init Command Ack Packet数据包后,立即建立事件的TCP连接并发送Init Event Request Packet数据包,包中携带的连接号即前面步骤中接收到的在Init Command Ack数据包中返回的连接号。Init Event Request数据包通过事件连接传输。
包结构如下:
Field | Size[Bytes] | Data Type |
---|---|---|
Length | 4 | UINT32 |
Packet Type | 4 | UINT32 |
Connection Number | 4 | UINT32 |
数据包示例:
对应地:
该数据包由响应端设备(Responder)通过事件连接通道回传给启动器设备,以告知启动器设备PTP-IP连接建立成功。
包结构如下:
Field | Size[Bytes] | Data Type |
---|---|---|
Length | 4 | UINT32 |
Packet Type | 4 | UINT32 |
数据包示例:
对应地:
初始化失败数据包。当PTP-IP连接建立失败时,该数据包由响应端设备(Responder)回传给启动器设备,以告知启动器设备连接建立失败及失败原因,失败原因被记录在Reason字段。接收到该数据包之后,启动器设备必须关闭先前步骤中建立的命令/数据连接。该数据包发出后,响应端设备亦应关闭相应的PTP-IP连接(由启动器设备发起的被拒绝的TCP连接)。Init Fail Packet可以通过任意的TCP连接传输。更多有关PTP-IP连接的建立可以参考PTP-IP连接一节内容。
Field | Size[Bytes] | Data Type |
---|---|---|
Length | 4 | UINT32 |
Packet Type | 4 | UINT32 |
Reason | 4 | UINT32 |
Reason字段包含了连接拒绝的错误码,该字段定义的错误码有以下几种:
操作请求数据包。该数据包在PTP-IP协议中用于传输在PTP标准协议**9.3.2 [1]**节定义的PTP操作请求。PTP-IP Operation Request Packet由启动器设备发送至响应端设备,并通过命令/数据通道传输。
包结构如下:
Field | Size[Bytes] | Data Type |
---|---|---|
Length | 4 | UINT32 |
Packet Type | 4 | UINT32 |
Data Phase Info | 4 | UINT32 |
Operation Code | 2 | UINT16 |
TransactionID | 4 | UINT32 |
Parameter1 | 4 | UINT32 |
Parameter2 | 4 | UINT32 |
Parameter3 | 4 | UINT32 |
Parameter4 | 4 | UINT32 |
Parameter5 | 4 | UINT32 |
- 如果Data Phase Info字段被设置为Data Out Phase,则在发送该数据包后接着必须要发送一个Start Data Packet包。
- 如果启动器设备需要发送空数据对象到响应端设备,有两个选项可选:1.将Data Phase Info字段设置为No data or data in phase,在这情况下响应端设备将会直接回应一个Operation Response Packet包,而不会等待Data Packet;2.将Data Phase Info字段设置为Data out Phase.在这种情况下,数据写阶段(data out phase)必须只包含一个Start Data Packet包,并将该包的Total Data Length字段设置为0x00000000,并且启动器设备必须不能发送后续的End Data Packet数据包。
实际该数据包结构如下:
对应地:
操作响应数据包。该数据包在PTP-IP协议中用于传输在PTP标准协议9.3.4 [1]节定义的PTP操作响应。PTP-IP Operation Response Packet数据包由响应端设备通过命令/数据通道回应给启动器设备。操作响应数据包仅在需要指示操作请求事务已经结束并且需要传递操作结果时才由响应端设备发送给启动器设备。
包结构如下:
Field | Size[Bytes] | Data Type |
---|---|---|
Length | 4 | UINT32 |
Packet Type | 4 | UINT32 |
Response Code | 2 | UINT16 |
TransactionID | 4 | UINT32 |
Parameter1 | 4 | UINT32 |
Parameter2 | 4 | UINT32 |
Parameter3 | 4 | UINT32 |
Parameter4 | 4 | UINT32 |
Parameter5 | 4 | UINT32 |
实际该数据包结构如下:
对应地:
事件数据包。该数据包用于传输在PTP标准协议**12.2 [1]**节中定义的事件。这些事件由响应端设备通过事件连接通道发送给启动器设备,以通知启动器设备响应端的状态变更。
包结构如下:
Field | Size[Bytes] | Data Type |
---|---|---|
Length | 4 | UINT32 |
Packet Type | 4 | UINT32 |
Event Code | 2 | UINT16 |
TransactionID | 4 | UINT32 |
Parameter1 | 4 | UINT32 |
Parameter2 | 4 | UINT32 |
Parameter3 | 4 | UINT32 |
开始数据传输数据包。该数据包在PTP-IP中用于标识数据传输的开始。其通过命令/数据通道传输,可以由任意一设备端发送,另一端接收。
包结构如下:
Field | Size[Bytes] | Data Type |
---|---|---|
Length | 4 | UINT32 |
Packet Type | 4 | UINT32 |
TransactionID | 4 | UINT32 |
Total Data Length | 8 | UINT64 |
数据包示例:
其中:
该数据包在PTP-IP中用于传输数据。Data Packet包只在数据阶段使用,且可以由当前数据流方向上的任意一端发送,另一端接收:在**数据读(data-in)阶段由响应端设备发送给启动器设备;在数据写(data-out)**阶段由启动器设备发送给响应端设备。Data Packet数据包走的是命令/数据的连接通道。
由于TCP传输是无错误、基于流的协议,通常不需要对大型的数据包进行拆包和粘包操作。不过可以使用基本的碎片机制来实现一个简单的数据传输取消机制,Data Packet不需要进行错误校验。
包结构如下:
Field | Size[Bytes] | Data Type |
---|---|---|
Length | 4 | UINT32 |
Packet Type | 4 | UINT32 |
TransactionID | 4 | UINT32 |
Data Payload | ? | UINT8 |
数据包示例:
其中:
终结数据传输的数据包。End Data Packet数据包在PTP-IP中用于标识数据阶段的结束,该数据包中也可以携带一些有用数据。该数据包只在一个事务的数据阶段使用,可以由数据流方向上的任意一端发送,另一端接收:在**数据读(data-in)阶段由响应端设备发送给启动器设备;在数据写(data-out)**阶段由启动器设备发送给响应端设备。
包结构如下:
Field | Size[Bytes] | Data Type |
---|---|---|
Length | 4 | UINT32 |
Packet Type | 4 | UINT32 |
TransactionID | 4 | UINT32 |
Data Payload | ? | UINT8 |
数据包示例:
其中:
Cancel Packet数据包用于取消传输事务,由启动器设备发送至响应端设备。该数据包在命令/数据连接通道和事件连接通道上发送。
包结构如下:
Field | Size[Bytes] | Data Type |
---|---|---|
Length | 4 | UINT32 |
Packet Type | 4 | UINT32 |
TransactionID | 4 | UINT32 |
心跳包。该数据包可用于PTP-IP的启动器设备和响应端设备,以检查对等设备是否仍然有效。当接收到该数据包时,设备必须立即响应一个Probe Response Packet数据包。如果在一段合理的时间内没有收到响应,则发出该数据包的设备将关闭与对端设备的PTP-IP会话。
包结构如下:
Field | Size[Bytes] | Data Type |
---|---|---|
Length | 4 | UINT32 |
Packet Type | 4 | UINT32 |
数据包示例:
其中前、后四个字节分别为Length字段和Packet Type字段。
使用该数据包时应要注意控制发送的频率以避免造成局域网过载:
- 启动器设备发送至响应端设备(I–>R):建议这个包只在PTP事务中使用(例如,当发出格式命令时,如果存储介质很大,响应时间可能会很长),以便检查响应端设备是否仍然处于活跃状态。
- 响应端设备发送至启动器设备(R–>I):建议仅当响应端设备接收到一个新的PTP-IP会话的请求,而另一个或多个其他会话处于活动状态时,才使用此包。在这种情况下,响应端设备可以检查现有的PTP-IP连接是否仍然处于活动状态。
- 建议在发送Probe Request Packet数据包和接收Probe Response Packet包之间设置10秒的超时时间。
心跳包的回应数据包。该数据包可用于PTP-IP的启动器设备和响应端设备,作为另一端的Probe Request Packet请求的响应。当接收到一个Probe Request Packet请求时应当立即回复这个数据包。
包结构如下:
Field | Size[Bytes] | Data Type |
---|---|---|
Length | 4 | UINT32 |
Packet Type | 4 | UINT32 |
数据包示例:
其中前、后四个字节分别为Length字段和Packet Type字段。
由启动器设备在PTP层发起的新会话请求将生成两个新的TCP连接,这两个连接即对应于PTP-IP层的**命令/数据(Command/Data)连接和事件(Event)连接。这两个TCP连接足够用来唯一标识其所属的会话,因此不需要将会话ID(SessionID)**作为独立的值从启动器设备发送到响应端设备。
在PTP-IP协议中,对设备的断开或者网络丢失的检测基于以下一些标准:
为了防止一个设备在事务的数据阶段用数据重载另一个设备,通常会实现一个数据流控制机制。不过在PTP-IP中不需要实现这样的机制,因为底层的TCP层会执行流控制操作。
TCP层在两个级别实现流控制:接收设备和网络,避免在低速接收和低速网络下数据泛滥。因此,在PTP-IP中采用TCP连接作为通信通道,直接解决了流量控制的问题。
有两种可能取消事务的情况:启动器设备请求取消或者响应端设备请求取消。
启动器设备为了取消正在进行的数据写阶段传输,必须在命令/数据通道和事件通道上发出一个Cancel Packet数据包,并停止任何正在命令/数据通道上的数据传输。当响应端设备在命令/数据通道或事件通道上收到Cancel Packet数据包时,必须尽可能快地中断并取消正在进行的事务,同时读取和丢弃所有属于当前事务(如果有)的剩余的数据包,并且向启动器设备回应一个附带有Transaction_Cancelled响应码的Operation Response Packet数据包。
启动器设备为了取消正在进行的数据读阶段传输,必须在命令/数据通道和事件通道上发出一个Cancel Packet数据包。响应端设备在命令/数据通道或事件通道上收到Cancel Packet数据包时,必须尽可能快地中断并取消正在进行的事务,并且向启动器设备回应一个附带有Transaction_Cancelled响应码的Operation Response Packet数据包。
启动器设备可以通过在命令/数据通道和事件通道上发出一个Cancel Packet数据包以在事务的任意阶段退出事务。如果取消的是当前的事务,则响应端设备必须回应一个附带有Transaction_Cancelled响应码的Operation Response Packet数据包。
响应端设备为了取消正在进行的数据写阶段传输,必须发送一个附带有Transaction_Cancelled或者其他标识数据传输中断原因的响应码的Operation Response Packet数据包。然后,响应端设备必须读取和丢弃所有属于当前事务的在命令/数据通道中的Data Packet数据包。
响应端设备为了取消正在进行的数据读阶段传输,必须在命令/数据通道上发送一个Operation Response Packet数据包,并且附带Transaction_Cancelled响应码或其他标识数据传输中断原因的响应码。
响应端设备可以通过发送附带Transaction_Cancelled响应码或其他标识数据传输中断原因的响应码的Operation Response Packet以在事务的任意阶段退出事务。
启动器设备为了取消一个异步操作,必须同时在命令/数据通道和事件通道发送一个包含该异步操作所属的事务ID的Cancel Packet数据包,启动器设备可以在任意时候发送这些数据包。
响应端设备将以PTP事件(例如Capture Complete event)结束操作。解释取消请求的逻辑由响应端设备的应用层负责。
该PTP-IP规范的二进制协议版本(BINARY PROTOCOL VERSION)是0x00010000(1.0版)。二进制协议版本由一个主要数字(高16位表示)和一个次要数字(低16位表示)组成。这个数字将增加,以表示较新的协议版本,方法如下:
如果没有实现设备发现协议,则每一个响应端设备和启动器设备应该通过以下端口号来初始化:
Port Name | Port No. | Type | Description |
---|---|---|---|
PTP-IP service | 15740 | TCP | 响应端设备等待TCP连接的默认端口,该端口由IANA批准。 |
PTP-IP协议的基础是TCP/IP协议,该协议的关键是寻址机制。响应端设备和启动端程序都将获得有效的IP地址。获取有效IP地址的方法有以下几种:
为了处理设备的TCP/IP属性配置,建议执行以下步骤:
在PTP-IP中,启动器设备可以通过以下几种方式配置连接到响应端设备的地址:
PTP规范第7.4条要求从其传输中支持设备发现和枚举。因此,PTP-IP 层应该至少实现以上这些服务中的一种。
不管使用什么服务发现和枚举,我们建议将设备的GUID作为广播包的一部分,这样启动端设备就能够过滤(如果需要的话)特定的设备,并生成选择性通知。
认证并不是PTP-IP层的职责。如果需要身份验证,则应该依赖于底层网络(物理/数据链路层)中可用的解决方案。设备绑定可以依赖于底层网络可用的机制或者基于PTP-IP层提供的机制在应用层实现,如下:
PTP-IP上下文中每一个设备都需要由一个可被用于设备绑定的全局唯一的标识:GUID(16字节的唯一数字)。对于这些设备,PTP-IP层提供了一个允许启动器设备和响应端设备互相交换GUID的机制。这进而允许应用层实现设备级访问控制(例如,一个新设备到达并被网络发现,该设备只能接受来自已知启动器设备的的选择性连接,或者只能启动到已知响应端设备的连接)。
无论使用什么服务发现和枚举方法,都建议将设备的GUID作为广播包的一部分,这样启动端设备就能够过滤(如果需要的话)特定的设备,并生成选择性通知。
本节不属于PTP-IP协议的范围。数据安全将依赖于底层网络(物理/数据链路层)中可用的解决方案。