MSTP包延时保证

BACnet有两种类型的服务,分为无确认与有确认。有确认服务的发送者(客户端)会等待应答直至超时。

通常情况下,无确认服务的包延时不会带来副作用。但对于有确认服务的请求包与应答包,过长的包延时将导致应答包因为超时而被抛弃,浪费了通讯带宽。

更有甚者,过迟到达的应答包可能导致应用层的逻辑错误!原因如下:

有确认服务的请求包头带有一个InvokeID,值范围0~255。应答包有同样的InvokeID。客户端通过这个InvokeID匹配请求与应答。在一个繁忙的客户端,InvokeID会快速耗尽, 此时只能回收重用已完成的服务的InvokeID。

如果一个有确认服务的应答包被过分延迟,客户端可能因为超时而结束服务,其InvokeID被回收,并被重新分配使用。此时被延迟的应答包被收到后,其InvokeID将被匹配到错误的服务。例如:

  • 客户端发出一个WriteProperty请求A,写设备X对象Y属性Z,分配的InvokeID为0。写入成功,但此请求包或者应答包延迟了。
  • 客户端等待超时而结束服务,InvokeID 0被回收。
  • 客户端发出一个WriteProperty请求B,写设备X对象U属性V,InvokeID又分配到0。写入失败。
  • 请求A的应答包先到达,由其InvokeID匹配到请求B。客户端认为请求B写入成功,造成应用层逻辑错误。

对高速的链路层如以太网或IP, 包延时通常是可忽略的,但是对于MSTP,有很多原因将造成过长的包延时:

  1. 信号噪声造成的令牌丢失或冲突。
  2. 不适当的设备配置(波特率,最大扫描站号,最大发包数)。
  3. 过高的流量。
  4. 过慢的设备。

为了避免InvokeID冲突及提高网络性能,版本2.0及以上的BACRouter实现了10秒钟 (参考BACnet的缺省APDU_Timeout,从v4.17起此延时修改为6秒钟) 的包延时保证,在收到后不能在此延时内完全转发的包将被抛弃。

虽然此策略可能造成服务无应答,但是比起错误应答,无应答是可以通过应用层的重试机制处理。