BACnet协议详解——应用层说明二

写在前面

又拖更了,对不起各位看官老爷了。实在是年后事情多,加上家属出差,只能先忙一忙其它的事情了。

3 BACnet APDU的传输

3.1 需确认的请求报文传输

客户端在发送需确认的请求报文之后,客户端将启动计时器。在收到关于需确认的请求报文的差错APDU、拒绝APDU、中止APDU、简单确认APDU或复杂确认APDU,则停止计时,并通知客户应用程序。如果计时器的时间超过了客户设备对象中的APDU超时(也就是device object里面的APDU_TimeOut属性,在客户端启动BACnet之前,该值必须被初始化进行设置),则重新发送该报文,同时计时器重新计时。所有需确认的请求报文的超时发送次数达到客户端设备对象的APDU重发次数(也就是客户端的device object里面的Number_Of_APDU_Retries属性,此属性也需要在启动BACnet之前进行设置),此时该报文将被丢弃,并通知客户端的应用程序。红字里面的两个属性值也需要在一些调试工具中需要进行设置,比如yabe,读到这里,就知道为什么要设置这些值以及这些值代表的是什么意思了。
数据的传输流程如下所示
在这里插入图片描述

3.2 分段的需确认请求报文的传输

分段的请求报文与没有分段请求报文的区别在于:

  • 最大的区别不用说,就是分段,分段请求报文需要发多次才能完成一个请求报文的传输

  • 分段的请求报文会用第一包数据中在客户端(也就是发送请求的设备)和服务端(也就是回复请求的设备)之间对每包数据传输大小(1~127)进行一个协商,也就是会存在这样一次对话:

    • 客户端在第一包数据中会说:我一包能传这么多数据,你能行不?
    • 服务端会在第一包数据的回复中说:
      • (一种回复)我是男人,当然行,我能收的比你多,但你就能传那么多数据,就按你能传的最多的来吧!(也就是服务端你在man,在能收,也不能告诉客户端发送超过它最大发送值的值
      • (另一种回复)很显然,服务端这次不够man,只回复了一个小于客户端能发送数据长度的值,但是必须大于等于1

那两者的相同点就是,每次发送和回复也得满足超时和重发次数的机制。
需要强调的一点就是,归属一个需确认的请求报文的所有分段报文的传输必须保证连续性,也就是两个分段报文之间的时间不能超过Tseg。Tseg就是发送端的Device Object里面的APDU_Segment_Timeout属性
传输过程如下图所示
在这里插入图片描述

3.3 分段的复杂确认报文的传输

这个与3.2的区别可以通过对比两个报文传输图看出来,就是:3.2是发送的数据需要分段处理,而3.3是回复的数据需要分段处理。
传输过程与3.2的区别就是:协商数据包大小的过程,是在服务端回复请求的第一包数据开始的,协商的过程跟3.2一样。其它需要注意的也参照3.2和3.1。
传输过程如下图所示:
在这里插入图片描述

3.4 分段确认APDU的传输

分段确认APDU是分段接收方设备用来确认发送方的信息。在以下四种情况下,设备应传送一个分段确认报文:

  1. 设备收到分段的报文的第一个分段。在这种情况下,用于确认的分段确认报文中参数‘否定确认(negative-ACK)’应设置为FALSE,以表明这是个肯定的确认;参数‘序号’应设置为0,以表明第一个分段已经被确认,分段的发送方可以继续发送后续的分段。
  2. 设备收到未确认的、有序的、数量为实际窗口尺寸的多个报文分段构成的序列。在这种情况下,用于确认的分段确认报文中参数‘否定确认’应设为FALSE,以表明这是个肯定的确认;,参数‘序号’应设置为此次所收的最后一个分段的‘序号’值,以表明包括该‘序号’在内的分段都被确认了,分段的发送方可以继续发送后续的分段。
  3. 设备收到一个乱序分段报文(可能表明丢失了某个分段)。在这种情况下,分段接收方将丢弃这个乱序分段。此处“乱序(out of order)”这个词的意思是指所收的分段的‘序号’不等于所预期的‘序号’。用于确认的分段确认报文中参数‘否定确认’应设为TRUE,以表明这是个否定的确认;参数‘序号’应设置为最后一次正确收到的分段的‘序号’值,以表明到此‘序号’值为止的所有分段都被确认了,分段的发送方可以继续发送后续的分段。
  4. 设备收到报文的最后一个分段。在这种情况下,用于确认的分段确认报文中参数‘否定确认’应设为FALSE,以表明这是个肯定的确认;参数‘序号’应设置为最后报文分段的‘序号’值,以表明所有分段都被确认了。

3.5 重复的APDU和报文分段

3.5.1 客户端事务处理状态机的中止

当使用BACnet标准定义的差错重传机制时,在报文传输的交互处理中,必然存在收到重复报文或分段的可能。在客户端,当发送了有证实请求APDU报文(或报文的第一个分段)之后,将创建事务处理状态机,进行事务处理。当出现以下四种情况之一时,客户端的事务处理中止,同时结束该事务处理状态机。

  1. 当收到服务器端设备发来的、包含有这个事务处理的调用标识符(invokeID)的五种报文时。这五种报文分别是:简单确认APDU、不分段的复杂确认APDU、差错APDU、拒绝APDU和中止APDU。
  2. 收到服务器发来的分段的复杂确认APDU的最后一个分段,并发送了相应的分段确认APDU后。
  3. 当超时重传次数用尽后。
  4. 在向服务器发送了包含有该事务处理的调用标识符的中止APDU后(例如:客户端中止这个事务处理)。
3.5.2 服务端事务处理状态机的中止

在服务端,当收到了证实请求APDU报文(或报文的第一个分段)之后,将创建事务处理状态机,进行事务处理。当出现以下四种情况之一时,服务器端的事务处理中止,同时结束该事务处理状态机。

  1. 当向客户端设备发送完成包含有这个事务处理的调用标识符的五种报文时。这五种报文分别是:简单确认APDU、不分段的复杂确认APDU、差错APDU、拒绝APDU和中止APDU。
  2. 当收到客户端设备发来的关于分段的复杂确认APDU最后一个分段的分段确认APDU之后.
  3. 当接收到客户端发来的包含有该事务处理调用标识符的中止APDU后。
  4. 在传输一个分段的复杂确认APDU的过程中,超时重传次数达到规定值仍未成功时。
3.5.3 重复报文的处理

重复报文或重复报文分段的处理过程如下:此处需要稍微注意下一下,因为mstp设备通过BACnet router跨网通信的时候,由于BACnet router的处理能力的问题,我们遇到过重复报文的情况。所以这里需要了解一下,不过也可以等遇到这种情况在深入的学习和分析。但各位看官也得知道遇到这种问题的时候,需要看文档的哪一部分吧!

  1. 当服务器接收到一个重复的有证实请求报文时,如果服务器具有识别重复的有证实请求报文的能力,则该重复的报文将被服务器丢弃。否则,服务器仍然响应这个重复的有证实请求报文,在这种情况下,客户将根据这个服务器响应报文中的调用标识符不与任何一个当前的事务处理状态机绑定这个情况,而丢弃这个响应报文。
  2. 当服务器接收到一个重复的有证实请求报文分段,即已经收到并针对该分段发送了分段确认报文时,服务器将丢弃这个重复的分段,并回传一个合适的分段确认APDU。任何分段都可由对等方地址(peer address)、调用标识符和分段的序号唯一确定。
  3. 当客户接收到一个重复的复杂确认报文分段,即已经收到并针对该分段发送了分段确认报文时,客户将丢弃这个重复的分段,并回传一个合适的分段确认APDU。任何分段都可由对等方地址、调用标识符和分段的序号唯一确定。
  4. 当一个设备接收到一个重复的分段确认APDU时,该设备将丢弃这个重复的分段确认APDU。

3.6 失效资源的处理

上述BACnet的差错重传过程,其具体实现需要客户和服务器两端提供一定的资源。这些资源通常是事务处理的各个细节,包括事务处理状态机、计时器、以及APDU或APDU分段缓冲区等。当差错重传过程失败时,这些相关的资源也变得失效,应被释放掉。资源释放的具体细节取决于系统的具体设计。作为设计建议,本协议给出了资源失效而应释放的依据:

  1. 在客户端,当收到对一个有证实请求APDU的完整响应后。
  2. 在客户端,当一个有证实请求APDU报文被重发了APDU重发次数属性所规定的次数,但仍未成功时。
  3. 在客户端,当一个有证实请求APDU分段被重发了APDU重发次数属性所规定的次数,但仍未成功时。
  4. 在服务器端,当发送了对某个有证实请求APDU的响应并收到相应的分段确认后。

4 应用层协议状态机

个人理解,这一部分不需要深入的理解,目前我还没有遇到状态机这些方面的问题,需要深入的了解这部分的内容。但是这部分的内容中有一些关于参数的可以来说明一下

4.1 变量与参数

  1. 变量包括:重发计数,分段重发计数等等,这些都是BACnet协议栈中需要定义的变量,用于计数等等作用。(如果你想深入了解一下协议栈的代码,看看这部分的内容也有一定的帮助,但你如果不看的话,直接看代码也应该大部分都能理解变量的意义

  2. 参数

    • Twait_for_seg : 这个参数是一个节点在发送完分段确认PDU后,等待后续报文分段的时间长度。这个时间长度值是节点的设备对象中APDU分段超时属性值的4倍。
    • Tout : 这个参数表示节点的设备对象中APDU超时属性值。
    • Nretry:这个参数表示节点的设备对象中APDU重发次数属性值。

5 应用层协议时许图

这部分的时序图都基本都挂在了第3部分的后面

应用层结语

其实,在应用层这部分不需要放入太多的精力,只需要把我标出红字的部分了解一下。或者把整个应用层大概的浏览一下而不需要花费太多的精力去理解,因为在你应用BACnet协议栈做开发的时候,这部分的知识并不是最关键的。BACnet协议的讲解肯定是自下而上的去讲,但是用BACnet的话,肯定是自上而下的或者说只用上层部分。只有当你把上层的应用弄明白,你慢慢在回来看这部分的讲解,就会有自己的理解。所以这部分,我的建议是,有时间就看一看,至少要浏览一下,没必要逐字逐句的去理解。

猜你喜欢

转载自blog.csdn.net/u012850592/article/details/129180137