a)BACnet的对象模型:
1.在BACnet标准中,所有的对象必须定义如下3个属性项:
Object_Identifier(对象标识符)
Object_Name(对象名称)
Object_Type(对象类型)
2.BACnet标准规定:任意一个“BACnet设备”均必须有且只有一个Device对象实例来标志。也就是说一个“BACnet设备”至少需要用两个BACnet对象进行描述。
由于BACnet设备只有一个Device对象实例,并且Device对象实例中包含有BACnet设备中所有对象实例表,因此Device对象在BACnet系统中作为BACnet设备的标识(Identifier)。这就要求Device对象的Object_Identifier属性不仅在BACnet设备内具有唯一性,而且还要求在BACnet互联网络内也是唯一的,而其它对象的Object_Identifier属性则只要求在BACnet设备内唯一。因此,在BACnet互连网络范围内,要索引一个非Device对象实例,就必须先索引该对象实例所在BACnet设备中的Device对象,然后在BACnet设备内就可以索引这个对象实例。
对象的“Object_Identifier”属性由4个字节组成,共32位,分为2个部分:1.对象类型标识域(10位) 2.对象实例编码域(22位)
1).对象类型标识域(10位)可以表示1024个对象类型,规定0~127为BACnet保留类型,如Analog-Input对象类型为0,这个在代码中可以看出:
typedef enum {
OBJECT_ANALOG_INPUT = 0,
OBJECT_ANALOG_OUTPUT = 1,
OBJECT_ANALOG_VALUE = 2,
OBJECT_BINARY_INPUT = 3,
OBJECT_BINARY_OUTPUT = 4,
OBJECT_BINARY_VALUE = 5,
OBJECT_CALENDAR = 6,
OBJECT_COMMAND = 7,
OBJECT_DEVICE = 8,
OBJECT_EVENT_ENROLLMENT = 9,
OBJECT_FILE = 10,
OBJECT_GROUP = 11,
OBJECT_LOOP = 12,
OBJECT_MULTI_STATE_INPUT = 13,
OBJECT_MULTI_STATE_OUTPUT = 14,
OBJECT_NOTIFICATION_CLASS = 15,
OBJECT_PROGRAM = 16,
OBJECT_SCHEDULE = 17,
OBJECT_AVERAGING = 18,
OBJECT_MULTI_STATE_VALUE = 19,
OBJECT_TRENDLOG = 20,
OBJECT_LIFE_SAFETY_POINT = 21,
OBJECT_LIFE_SAFETY_ZONE = 22,
OBJECT_ACCUMULATOR = 23,
OBJECT_PULSE_CONVERTER = 24,
OBJECT_EVENT_LOG = 25,
OBJECT_GLOBAL_GROUP = 26,
OBJECT_TREND_LOG_MULTIPLE = 27,
OBJECT_LOAD_CONTROL = 28,
OBJECT_STRUCTURED_VIEW = 29,
OBJECT_ACCESS_DOOR = 30,
/* 31 was lighting output, but BACnet editor changed it... */
OBJECT_ACCESS_CREDENTIAL = 32, /* Addendum 2008-j */
OBJECT_ACCESS_POINT = 33,
OBJECT_ACCESS_RIGHTS = 34,
OBJECT_ACCESS_USER = 35,
OBJECT_ACCESS_ZONE = 36,
OBJECT_CREDENTIAL_DATA_INPUT = 37, /* authentication-factor-input */
OBJECT_NETWORK_SECURITY = 38, /* Addendum 2008-g */
OBJECT_BITSTRING_VALUE = 39, /* Addendum 2008-w */
OBJECT_CHARACTERSTRING_VALUE = 40, /* Addendum 2008-w */
OBJECT_DATE_PATTERN_VALUE = 41, /* Addendum 2008-w */
OBJECT_DATE_VALUE = 42, /* Addendum 2008-w */
OBJECT_DATETIME_PATTERN_VALUE = 43, /* Addendum 2008-w */
OBJECT_DATETIME_VALUE = 44, /* Addendum 2008-w */
OBJECT_INTEGER_VALUE = 45, /* Addendum 2008-w */
OBJECT_LARGE_ANALOG_VALUE = 46, /* Addendum 2008-w */
OBJECT_OCTETSTRING_VALUE = 47, /* Addendum 2008-w */
OBJECT_POSITIVE_INTEGER_VALUE = 48, /* Addendum 2008-w */
OBJECT_TIME_PATTERN_VALUE = 49, /* Addendum 2008-w */
OBJECT_TIME_VALUE = 50, /* Addendum 2008-w */
OBJECT_NOTIFICATION_FORWARDER = 51, /* Addendum 2010-af */
OBJECT_ALERT_ENROLLMENT = 52, /* Addendum 2010-af */
OBJECT_CHANNEL = 53, /* Addendum 2010-aa */
OBJECT_LIGHTING_OUTPUT = 54, /* Addendum 2010-i */
/* used for bit string loop */
PROPRIETARY_BACNET_OBJECT_TYPE = 128,
MAX_BACNET_OBJECT_TYPE = 1024
/* Enumerated values 0-127 are reserved for definition by ASHRAE. */
/* Enumerated values 128-1023 may be used by others subject to */
/* the procedures and constraints described in Clause 23. */
} BACNET_OBJECT_TYPE;
2)对象实例编码域(22位)可以表示4M个对象实例,也就是说,Device对象类型的实例数在一个BACnet互联网络中最多可以达到4M个,而其它对象类型在一个BACnet设备内就可以达到4M个。MARK:如果Device对象实例智能达到4M个的话,比起IPV4地址还要少,为什么还要开发IPV6呢?
3.如果将BACnet对象与C/C++相比较的话,BACnet对象只是相当于一个数据结构(structure),因为BACnet对象没有定义所谓的方法(method)。
b)BACnet的应用服务:
1.在楼宇自控网络环境中,互操作可以看做是BACnet对象间的信息交换。这种信息交换是从BACnet对象外部进行的,因此对BACnet对象的访问就必须定义操作的命令或消息,并要求包含BACnet对象的宿主环境能够接受、发送和解释命令或消息的语义,并对BACnet对象的属性进行操作,然后再由宿主环境中的其他进程或县城根据BACnet对象属性值进行相关的楼宇功能,如打开/关闭阀门等。
2.在BACnet标准中,BACnet对象只是由属性组成的“数据结构”,如何对这些数据结构进行访问和管理则是应用服务的主要功能。除此之外,应用服务还提供了非对象数据访问的功能,这些功能是所有网络均应具有的功能,所以这些功能通常不直接与BACnet标准中定义的对象有关,主要用于远程设备管理、虚拟终端和网络安全等。
3.当应用程序向应用层协议实体进行请求时,就必须提供请求参数。这些参数除应用程序通信的内容以外,还必须提供与通信过程处理有关的参数,用于控制通信过程。这种通信过程处理参数通常称为协议的“接口控制信息ICI”。一般ICI包括DA SA NP DER。
服务原语 | DA | SA | NP | DER | ||
CONF_SERV.request | 有 | 无 | 有 | 无 | ||
CONF_SERV.indication | 有 | 有 | 有 | 有 | ||
CONF_SERV.responce | 有 | 无 | 有 | 有 | ||
CONF_SERV.confirm | 有 | 有 | 有 | 无 | ||
UNCONF_SERV.request | 有 | 无 | 有 | 无 | ||
UNCONF_SERV.indication | 有 | 有 | 有 | 无 |
DA:目的地址,接受服务原语的目标设备的地址
SA:源地址,发送服务原语的源设备的地址
NP:网络优先级,用于决定APDU的优先级
DER:期待回复数据标志data_expection_reply,用来指明服务是否需要回复或确认服务原语
MARK:
4.证实服务与非证实服务
5.协议状态机
6.常用的应用服务
(以下内容截取自bacnet协议)http://download.csdn.net/detail/forsakening/5174569
本协议的第13节到第17节以及第24节用列表的形式,明确地描述了BACnet服务原语中的参数。每个表由5列组成,一列是服务参数名称,其它四列分别对应请求“Req”、指示 “Ind”、响应“Rsp”和证实“Cnf”原语。对于非证实服务,“Req”与“Cnf”所对应的列是空缺的。表的每一行包含了一个参数或子参数,同时在每种服务原语所在的列,都用一个符号指出该参数在这种服务原语中的使用类型。这些符号按ISO关于约定用法方面的技术报告(ISO TR 8509)的建议,命名如下:
M—对于此原语,该参数是必需的。
U—此参数是用户选择的,可以不提供。
C—此参数是有条件的(Conditional),它取决于其它一些参数。
S—此参数是个选择参数,即从多个可能的选择参数集合中选取一个。组成选择参数集合的参数在表中按如下方式表示:
(a) 选择参数集合中的每个参数,用符号“S”表示;
(b) 表中属于同一选择参数集合的每个参数名称,位于参数列中相同的缩格位置;
对于同一选择参数集合所包含的参数,在表中用相同的缩格来表示其属于该参数组。也就是说,位于同一“高层”参数且具有相同水平缩格的参数,都属于同一选择集合。
在符号M、U、C或S后跟着有符号“(=)”,这表示此列的服务原语中的参数与在(=)左边的字母单独所在列的服务原语中的参数,在语义上是相等的。例如,在指示原语列中符号为“M(=)”,而“M”单独在请求原语列中,这就表示指示原语中的参数与请求原语中对应的参数,语义上是相等的。
Who-Has和I-Have服务
一个发送的BACnet用户使用Who-Has服务确定一些其它BACnet设备的设备对象标识符和网络地址,这些设备的本地数据库中包含有具有给定的对象名称属性或者给定的对象标识符属性的对象。设备使用I-Hava服务响应Who-Has服务请求,或者通告自己有一个具有给定的对象名称属性或者对象标识符属性的对象。可以在任何时候发送I-Hava服务请求,并不要求一定要在接收到Who-Has服务请求之后才能够使用。Who-Has服务和I-Hava服务是无证实的服务。
16.8.1 Who-Has服务结构
表16-8表示Who-Has服务原语的结构,表中所用的术语和符号在5.6节中给出了解释。
表16-8 Who-Has服务原语结构
参数名称 | Req | Ind |
参数(Argument) 设备实例低阈值范围(Device Instance Range Low Limit) 设备实例高阈值范围(Device Instance Range High Limit) 对象标识符(Object Identifier) 对象名称(Object Name) | M U U S S | M(=) U(=) U(=) S(=) S(=) |
16.8.1.1 参数
这个参数为Who-Has无证实服务请求传送参数值。
16.8.1.1.1设备实例低阈值范围
这个参数是无符号整型类型,取值范围是0-4,194,303(22个比特位,对应于前面所说的对象实例的范围)。这个参数与‘设备实例高阈值范围’参数一起定义有资格使用I-Hava服务响应本服务的设备,这些设备还满足16.8.1.3节和16.8.1.4节规定的‘对象标识符’准则或者‘对象名称’准则。如果‘设备实例低阈值范围’参数存在,则‘设备实例高阈值范围’参数也必须存在。只有那些设备对象标识符属性值实例在范围(‘设备实例低阈值范围’ ≤ 对象标识符属性值实例 ≤ ‘设备实例高阈值范围’)之内的设备有资格进行响应。‘设备实例低阈值范围’参数值小于等于‘设备实例高阈值范围’参数值。如果省略‘设备实例低阈值范围’和‘设备实例高阈值范围’参数,则所有接收到这个报文的设备都有资格使用I-Hava服务进行响应。
16.8.1.1.2设备实例高阈值范围
这个参数是无符号整型类型,取值范围是0-4,194,303。这个参数与‘设备实例低阈值范围’参数一起定义有资格使用I-Hava服务响应本服务的设备,这些设备还满足16.8.1.3节和16.8.1.4节规定的‘对象标识符’准则或者‘对象名称’准则。如果‘设备实例高阈值范围’参数存在,则‘设备实例低阈值范围’参数也必须存在。只有那些设备对象标识符属性值实例在范围(‘设备实例低阈值范围’ ≤ 对象标识符属性值实例 ≤ ‘设备实例高阈值范围’)之内的设备有资格进行响应。‘设备实例高阈值范围’参数值大于等于‘设备实例低阈值范围’参数值。如果省略‘设备实例低阈值范围’和‘设备实例高阈值范围’参数,则所有接收到这个报文的设备都有资格使用I-Hava服务进行响应。
16.8.1.1.3 对象标识符
这个参数是BACnet对象标识符类型,传送本服务正在定位的对象的对象标识符属性值。如果省略这个参数,则必须存在‘对象名称’参数。如果这个参数存在,则只有那些包含有其对象标识符属性值与这个参数值匹配的对象的设备,同时又满足16.8.1.1节和16.8.1.2节规定的资格要求,可以使用I-Hava服务进行响应。
16.8.1.1.4 对象名称
这个参数是字符串类型,传送本服务正在定位的对象的对象名称属性值。如果省略这个参数,则必须存在‘对象标识符’参数。如果这个参数存在,则只有那些包含有其对象名称属性值与这个参数值匹配的对象的设备,同时又满足16.8.1.1节和16.8.1.2节规定的资格要求,可以使用I-Hava服务进行响应。
16.8.2 Who-Has服务过程
发送方BACnet用户通常使用广播地址发送Who-Has服务请求。如果‘设备实例低阈值范围’和‘设备实例高阈值范围’参数存在,则那些接收到这个报文的BACnet用户设备中,设备的对象标识符属性值实例在范围(‘设备实例低阈值范围’ ≤ 对象标识符属性值实例 ≤ ‘设备实例高阈值范围’)之内的,有资格进行响应。如果‘对象名称’参数存在,则只有那些有资格的设备,同时又包含有其对象名称属性值与‘对象名称’参数值匹配的对象的设备,使用I-Hava服务请求进行响应。如果‘对象标识符’参数存在,则只有那些有资格的设备,同时又包含有其对象标识符属性值与‘对象标识符’参数值匹配的对象的设备,使用I-Hava服务请求进行响应。
16.8.3 I-Have服务结构
表16-9表示I-Have服务原语的结构,表中所用的术语和符号在5.6节中给出了解释。
表16-9 I-Have服务原语结构
参数名称 | Req | Ind |
参数(Argument) 设备标识符(Device Identifier) 对象标识符(Object Identifier) 对象名称(Object Name) | M M M M | M(=) M(=) M(=) M(=) |
16.8.3.1 参数
这个参数为I-Have无证实服务请求传送参数值。
16.8.3.1.1设备标识符
这个参数是BACnet对象标识符类型,是起始I-Have服务请求的设备的设备对象标识符。
16.8.3.1.2 对象标识符
这个参数是BACnet对象标识符类型,传送在起始设备中作为定位而通告的对象的对象标识符。这个标识符对应被通告对象的对象标识符属性值。
16.8.3.1.3 对象名称
这个参数是字符串类型,传送在起始设备中作为定位而通告的对象的对象名称。这个标识符对应被通告对象的对象名称属性值。
16.8.4 I-Have服务过程
发送方BACnet用户广播I-Have服务请求。根据应用的需要,这个广播可以是在本地网络范围内的广播,也可以是在一个远程网络范围内的广播,或者是在所有网络中的全局广播。如果正在被发送的I-Have服务请求是对前面接收到的一个Who-Has服务的响应,则要按照发送Who-Has服务的BACnet用户应该接收到的I-Have服务结果的方式发送这个I-Have服务请求。因为这个请求是无证实的,所以不要求进一步的操作。一个BACnet用户可以在任何时候发送一个I-Have服务请求。
16.9 Who-Is和I-Am服务
一个发送方BACnet用户使用Who-Is服务确定在同一个互联网上的其它BACnet设备的设备对象标识符和网络地址,Who-Is服务是一个无证实服务,这个服务可以用于下列两种情况:(1) 确定在网络上的所有设备的设备对象标识符和网络地址,或者(2) 确定某个已知其设备对象标识符但是不知其网络地址的设备的网络地址。I-Am服务也是一个无证实的服务,这个服务用于响应Who-Is服务请求。I-Am服务也可以在任何时候被发送,并不一定要求只有接收到Who-Is服务请求之后才能够发送I-Am服务请求。特别是,当一个设备刚启动之后,可能需要广播一个I-Am服务请求。如果发送I-Am服务请求的设备与接收这个报文的设备处于同一个本地网络,则可以从I-Am服务请求报文中的MAC地址推导出发送设备的网络地址。如果发送设备位于一个远程网络,则可以从报文的NPCI域中推导出设备的网络地址。
16.9.1 Who-Is服务结构
表16-10表示Who-Is服务原语的结构,表中所用的术语和符号在5.6节中给出了解释。
表16-10 Who-Is服务原语结构
参数名称 | Req | Ind |
参数(Argument) 设备实例低阈值范围(Device Instance Range Low Limit) 设备实例高阈值范围(Device Instance Range High Limit) | M U U | M(=) U(=) U(=) |
16.9.1.1 参数
这个参数为Who-Is无证实服务请求传送参数值。
16.9.1.1.1设备实例低阈值范围
这个参数是无符号整型类型,取值范围是0-4,194,303。这个参数与‘设备实例高阈值范围’参数一起定义有资格使用I-Am服务响应本服务的设备。如果‘设备实例低阈值范围’参数存在,则‘设备实例高阈值范围’参数也必须存在。只有那些设备对象标识符属性值实例在范围(‘设备实例低阈值范围’ ≤ 对象标识符属性值实例 ≤ ‘设备实例高阈值范围’)之内的设备有资格进行响应。‘设备实例低阈值范围’参数值小于等于‘设备实例高阈值范围’参数值。如果省略‘设备实例低阈值范围’和‘设备实例高阈值范围’参数,则所有接收到这个报文的设备都有资格使用I-Am服务进行响应。
16.9.1.1.2设备实例高阈值范围
这个参数是无符号整型类型,取值范围是0-4,194,303。这个参数与‘设备实例低阈值范围’参数一起定义有资格使用I-Am服务响应本服务的设备。如果‘设备实例高阈值范围’参数存在,则‘设备实例低阈值范围’参数也必须存在。只有那些设备对象标识符属性值实例在范围(‘设备实例低阈值范围’ ≤ 对象标识符属性值实例 ≤ ‘设备实例高阈值范围’)之内的设备有资格进行响应。‘设备实例高阈值范围’参数值大于等于‘设备实例低阈值范围’参数值。如果省略‘设备实例低阈值范围’和‘设备实例高阈值范围’参数,则所有接收到这个报文的设备都有资格使用I-Am服务进行响应。
16.9.2 Who-Is服务过程
发送方BACnet用户通常使用广播地址发送Who-Is服务请求。如果省略了‘设备实例低阈值范围’和‘设备实例高阈值范围’参数,则所有这个报文的BACnet用户设备都使用I-Am服务单独响应自己的设备对象标识符。如果‘设备实例低阈值范围’和‘设备实例高阈值范围’参数存在,则那些接收到这个报文的BACnet用户设备中,设备的对象标识符属性值实例在范围(‘设备实例低阈值范围’ ≤ 对象标识符属性值实例 ≤ ‘设备实例高阈值范围’)之内的设备,使用I-Am服务请求响应它们的设备对象标识符。
16.9.3 I-Am服务结构
表16-11表示I-Am服务原语的结构,表中所用的术语和符号在5.6节中给出了解释。
表16-11 I-Am服务原语结构
参数名称 | Req | Ind |
参数(Argument) I-Am设备标识符(I-Am Device Identifier) 最大APDU长度支持(Max APDU Length Accepted) 分段支持(Segmentation Supported) 生产商标识符(Vendor Identifier) | M M M M M | M(=) M(=) M(=) M(=) M(=) |
16.9.3.1 参数
这个参数为I-Am无证实服务请求传送参数值。
16.9.3.1.1 I-Am设备标识符
这个参数是BACnet对象标识符类型,是起始I-Am服务请求的设备的设备对象标识符。
16.9.3.1.2最大APDU长度支持
这个参数是无符号整型类型,传送可以包含在一个单独的、不可分割的APDU中的最大的字节数量。这个参数值应该与设备对象的最大APDU长度支持属性值相同。参见12.9.17节。
16.9.3.1.3分段支持
这个参数是BACnet分段类型,传送起始I-Am服务请求的设备处理分段报文的能力。这个参数值应该与设备对象的分段支持属性值相同。参见12.9.18节。
16.9.3.1.4生产商标识符
这个参数是16位无符号整型类型,传送起始I-Am服务请求的设备的生产商的标识符。这个参数值应该与设备对象的生产商标识符属性值相同。参见12.9.6节和23节。
16.9.4 I-Am服务过程
发送方BACnet用户广播I-Am服务请求。根据应用的需要,这个广播可以是在本地网络范围内的广播,也可以是在一个远程网络范围内的广播,或者是在所有网络中的全局广播。如果正在被广播的I-Am服务请求是对前面接收到的一个Who-Is服务的响应,则要按照发送Who-Is服务的BACnet用户应该接收到的I-Am服务结果的方式发送这个I-Am服务请求。因为这个请求是无证实的,所以不要求进一步的操作。一个BACnet用户可以在任何时候发送一个I-Am服务请求。
在bacnet-stack-0.8.0工程中对应的I-Am的APDU编码函数为:
/* encode I-Am service */
int iam_encode_apdu(
uint8_t * apdu,
uint32_t device_id,
unsigned max_apdu,
int segmentation,
uint16_t vendor_id)
{
int len = 0; /* length of each encoding */
int apdu_len = 0; /* total length of the apdu, return value */
if (apdu) {
apdu[0] = PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST;
apdu[1] = SERVICE_UNCONFIRMED_I_AM; /* service choice */
apdu_len = 2;
len =
encode_application_object_id(&apdu[apdu_len], OBJECT_DEVICE,
device_id);
apdu_len += len;
len = encode_application_unsigned(&apdu[apdu_len], max_apdu);
apdu_len += len;
len =
encode_application_enumerated(&apdu[apdu_len],
(uint32_t) segmentation);
apdu_len += len;
len = encode_application_unsigned(&apdu[apdu_len], vendor_id);
apdu_len += len;
}
return apdu_len;
}
实际接收到得I-Am报文的APDU为:
对比这些参数:
I-Am设备标识符(I-Am Device Identifier)
最大APDU长度支持(Max APDU Length Accepted)
分段支持(Segmentation Supported)
生产商标识符(Vendor Identifier)
发现确实是按照协议标准所说,这些参数都M的,即是必须的