文章目录
- 写在前面
- 1. 应用层模型
- 1.1 需确认的应用层服务
- 1.2 无需确认的应用层服务
- 2 BACnet报文的分段
- 2.1 报文分段规则
- 2.1.1 APDU数据流的分段规则
- 2.1.2 APDU最大长度的确定
- 2.1.3 可接受的最大分段数
- 2.2 分段协议控制信息(PCI)
写在前面
年关将至,事情有点多,耽误了原本定好的每两周更新一次的任务。本来也想着把应用层用一章的blog来说的,不过太多的,分开来讲吧!最后祝大家新年快乐,身体健康,学啥会啥。年后见啦~
1. 应用层模型
建立这个模型的目的是为了清楚地描述应用层与应用程序之间的交互(interaction)、应用层与协议栈中下面各层次的关系、以及应用层与远程设备中应用层的对等交互。
一个应用进程(Application Process)是指在一个系统中,针对某个应用而进行信息处理的功能模块。如上图所示,在应用进程中有一部分位于应用层之外,它们与通信功能无关,这些部分都不属于BACnet标准的规范范围。我们将应用进程中位于应用层内的部分称为应用实体(Application Entity)。换句话说,一个应用实体是应用进程中与BACnet通信功能相关的部分。一个应用程序(application program)通过应用编程接口API(Application Program Interface)与应用实体进行交互。编程接口不在BACnet中定义,但是在具体的实现中它总是一个函数、过程或子程序的调用。在上图中,阴影部分是应用进程位于BACnet应用层中的部分。
一个应用实体由两部分组成,分别是BACnet用户元素(User Element)和BACnet应用层服务元素ASE(Application Service Element)。BACnet应用层服务元素描述了应用服务或功能的集合。BACnet用户元素执行多种功能,并且支持本地的API,它描述每个应用服务中“服务过程(service procedure)”的实现。BACnet用户元素负责三个方面的事务,第一,保存事务处理的上下文信息,包括产生请求标识符(ID),记录哪个标识符是与哪个设备发出的应用服务响应(或对哪个设备的应用服务请求)相对应的;第二,保存超时重传机制所需的超时计时器;第三,将一个设备的行为映射成为BACnet对象。
,BACnet中两个对等应用进程间的信息交换,被表示成抽象服务原语的交换。这些服务原语用来传递一些特定的服务参数。本协议定义四种服务原语:请求(request)、指示(indication)、响应(response)和证实(confirm)。包含在这些原语中的信息,由本标准中定义的各种协议数据单元(PDU:Protocol Data Unit)传递。
有证实(confirmed)服务的符号标记是CONF_SERV,指明使用BACnet的有证实服务PDU。无证实(unconfirmed)服务的符号标记是UNCONF_SERV,指明使用BACnet的无证实服务PDU。分段确认(segment acknowledge)服务的符号标记是SEGMENT_ACK,指明使用BACnet的分段确认PDU。差错(error)服务的符号标记是ERROR,指明使用BACnet的差错PDU。拒绝(reject)服务的符号标记是REJECT,指明使用BACnet的拒绝PDU。中止(abort)服务的符号标记是ABORT,指明使用BACnet的中止PDU。
当应用程序需要同远程的应用进程通讯时,它所要进行的操作是通过API访问本地的BACnet用户元素。一些 API 参数,例如服务请求要发送到的设备的身份(地址)和协议控制信息,直接向下传递到网络或数据链路层。 其余的参数组成了一个应用程序服务原语,它从 BACnet 用户元素传递到 BACnet ASE。从概念上来讲,由应用层服务原语产生的应用层协议数据单元APDU(application protocol data unit),构成了网络层服务原语的数据部分,并通过网络层服务访问点NSAP(Network Service Access Point)下传到网络层。按照这样的方式,这个请求进一步下传到本地设备协议栈的以下各层。整个过程如下图所示。于是,报文就这样被传送到远程的设备,并在远程设备协议栈中逐级上传,最后指示原语看起来似乎是直接从远程的BACnet应用层服务元素上传到远程的BACnet用户元素。同样,任何从远程设备发回的响应,也是以这样的方式回传给请求设备的。
应用实体通过API与应用程序除了交换服务原语和服务参数之外,还交换接口控制信息ICI(interface control information)参数。ICI的具体内容取决于服务原语的类型。应用实体将接收到的ICI参数下传至下面各层,从而使得各层可以构建自己的PDU。而由应用实体回传给应用程序的ICI参数,则包含了下面各层从各自PDU中得到的信息。
通过API与各种服务原语交换信息的ICI参数包括:
- “目的地址DA(destination_address)”:将要接收服务原语设备的地址。
- “源地址SA(source_address)”:发送服务原语的设备的地址。
- “网络优先级NP(network_priority)”
- “期待回复数据DER(data_expecting_reply)”:一个逻辑值参数,用来指明某个服务是否需要一个回复的服务原语。
BACnet设备(BACnetDevice)是指任何一种支持用BACnet协议进行数字通信的真实的或者虚拟的设备。每一个BACnet设备必须且只能包含一个设备(Device)对象。每一个BACnet设备,都由一个NSAP唯一定位。在NASP中,包含了一个网络编号和一个MAC地址。
在多数情况下,一个BACnet设备就是一个物理设备。然而在某些情况下,一个单一的物理设备也可以形成多个“虚拟的” BACnet设备。
1.1 需确认的应用层服务
BACnet基于客户/服务器通信模型定义了需确认的应用层服务。客户方通过具体的服务请求实例向服务器方请求服务,服务器方通过响应请求来为客户方提供服务,这种关系如下图所示。在交互过程中,担当客户角色的BACnet 用户,称为请求方BACnet 用户;担当服务器角色的BACnet 用户,称为响应方BACnet 用户。
需确认应用层服务的具体过程如下:
- 由请求方BACnet用户发出一个需确认服务请求原语(CONF_SERV.request),形成请求PDU,发送给响应方BACnet用户。
- 当这个请求PDU到达响应方BACnet用户时,响应方BACnet用户则收到一个需确认服务指示原语(CONF_SERV.indication)
- 同时,由响应方BACnet用户发出的一个需确认服务响应原语(CONF_SERV.response),形成响应PDU回传给请求方BACnet用户。
1.2 无需确认的应用层服务
在无需确认的应用层服务中,只有“发送方BACnet用于”和“接收方BACnet用户”,BACnet标准用它们来定义无需确认应用层的服务过程。
2 BACnet报文的分段
为了实现长报文(长度大于通信网络、收/发设备所支持的长度)的传输,BACnet采取了应用层报文分段的机制来对报文进行分段。在BACnet中只有需确认请求(Confirmed-Request)和复杂确认(Complex-ACK)报文可能需要分段,因此分段还是BACnet的一个可选特性。报文分段这块内容其实不需要太多深入,如果用BACnet协议栈的话,协议栈在内部就包含这部分内容,而不需要你去单独的了解实现,但是在使用的过程中,如果遇到这方面的问题,需要一些皮毛性的知识去调试就可以了。
2.1 报文分段规则
2.1.1 APDU数据流的分段规则
- 一个完整的报文尽可能作为一个APDU发送
- 当一个完整的报文不可能作为一个APDU发送时,则应分段成最少个数的多个APDU发送
- 对报文进行分段时,必须以字节作为最小的分割单位
2.1.2 APDU最大长度的确定
在BACnet中,APDU的最大长度不是固定的,其具体值是下列各长度值中的最小值:
- 设备所能发送的APDU的最大长度。这个长度一般与本地设备的缓冲区大小等因素有关
- BACnet互联网所能传输到远程设备的APDU的最大长度。这个长度一般由本地、远程、以及中间传输网络的数据链路所允许的网络层协议数据单元(NPDU)的最大长度所决定
- 远程设备所能接收的APDU的最大长度,其值不能小于50个字节
如果报文的发送设备是请求方BACnet用户,也就是说要发送的APDU是BACnet需确认请求PDU(BACnet-Confirmed-Request-PDU) 或者是BACnet无需确认请求PDU ( BACnet-Unconfirmed-Request-PDU), 这时远程设备所能接受APDU的最大长度,由远程设备对象的最大APDU长度支持(Max_APDU_Length_Accepted)属性所确定。这个属性值可以通过ReadProperty服务来读取该属性值;也可以向远程设备发送一个Who-Is服务请求,使其回复一个I-Am服务响应,通过读取其中的通过读取其中的‘最大APDU长度支持(Max APDU Length Accepted)’参数来获得该属性值。
如果报文的发送设备不是请求方BACnet用户,也就是说要发送的APDU是BACnet 复杂确认PDU(BACnet-Complex-ACK-PDU),这时远程设备所能接受的APDU的最大长度,由本报文所响应的那个BACnet需确认请求PDU中的‘最大APDU长度支持’参数所确定。
上述的各种约束值最终决定了最大可传输长度的大小。需要注意的是,除非各个约束值都取最小值,否则最大可传输长度(maximum-transmittable-length)不会是一个常数。
2.1.3 可接受的最大分段数
在Confirmed-Request或者ComplexACK消息中可以传输的分段的最大值应该是以下情况中的最小值:
- 由于受到本地资源和本地事务限制而导致的可以在设备中能传输的分段的最大值
- 可以被远程对等设备接受的最大分段数
2.2 分段协议控制信息(PCI)
为了支持报文分段,BACnet 规定BACnet需要确认的PDU和BACnet复杂确认PDU的头部,包含两个布尔型参数,分别是‘报文分段(Segmented Message)’和‘后继(More Follows)’。
如果报文经编码处理后生成的APDU的长度,小于或等于2.1节所确定的最大可传输长度的值,则‘报文分段’和‘后继’两个参数都应设置为FALSE。
反之,如果报文经编码处理后生成的APDU的长度,大于2.1节所确定的最大可传输长度的值,则所有的分段中‘报文分段’参数都应设置为TRUE;并且除了最后一个分段,其它所有分段中的‘后继’参数也应设置为TRUE。
此外,由有需要确认报文或复杂确认报文的每个分段所生成APDU的头部,还有两个条件参数。第一个条件参数是‘序号(Sequence Number)’,这个八位二进制无符号整数被报文分段的发送方用来指定当前分段在整个报文分段序列中的位置。另一个条件参数是‘预设窗口尺寸(Proposed Window Size)’,它同样是一个八位二进制无符号整数。报文分段的发送方用该参数来指明,在收到一个分段确认(SegmentAck)报文之前,它预备发送的最大报文分段数。这两个参数在分段报文发送中的具体用法将在下一节中进一步说明。
起始分段中的‘序号’参数应设置为0。报文分段接收方在收到一个或一组报文后,会向发送方发送一个包含有‘序号’参数的分段确认PDU。序号的大小,等于最近一次成功接收到的分段的‘序号’参数值。这样,这个分段确认PDU不但用来请求发送方继续发送后一个或一组分段,还用来对先前一个分段或者是先前所有未被确认的分段(当Window Size值大于1时)的确认。
当然,在分段传输交互过程中的任何一方如果想中止交互过程,只要发送一个中止PDU(Abort-PDU)即可。