原创不易
转载请附上链接:https://blog.csdn.net/SGJcgj/article/details/119417655
本文是对于IEC62056协议族,即DLMS协议族的中文说明手册 本文并没有包含DLMS协议族的全部,但解释了在应用中可能出现的大多数情况 本文的目的是为电能量数据采集终端提供与使用DLMS协议族的电能表通讯的协议说明
本文参考文献如下:
(1)DLMS User Association , COSEM Identification System andInterface Objects , Third Edition
(2)IEC62056 -53 Electricitymetering - Data exchange for meter reading, tariff and load control -Part 53: COSEM applicationlayer
(3)IEC62056 -46Electricity metering - Data exchange for meter reading, tariff and load control -Part 46: Data link layerusing HDLC protocol
(4)IEC62056 -42 Electricity metering - Data exchange for meter reading, tariff and load control -Part 42: Physical layer servicesand procedures for connection-orientedasynchronous data exchange
(5)IEC62056 -61 Electricity metering - Data exchange for meter reading, tariff and load control -Part 61: Object identificationsystem (OBIS)
(6)Amber Management logical device-FR:AMBER/FW TECH_SPEC MANAGEMENT_LOGICAL_DEVICE
(7)Amber Electricity Logical Device - FR:AMBER/FWTECH_SPEC ELECTRICITY_LOGICAL_DEVICE
(8)A Layman’s Guide to a Subset of ASN.1, BER, and DER-AnRSA Laboratories Technical Note
Burton S. KaliskiJr.Revised November 1, 1993
(9)IEC61334采用配线载波的配电自动化,译文汇编
一、DLMS协仪模型
属性和访问方法都是在啊cosen里面。就好像那个oad,通过dlms协议来访问cosen对象的方法和属性。好像了解了这个的关系了哈,这个dlms就是套报文的规范,在每个层该怎么用。Cosen就是定义了一些接口类,以及类里面的方法和属性。他们并不干扰,就是各自干各自的事儿。
其实从这个图就可以看出,dlms协议就是更加详细的来表示。请求/响应。
他类构建好了只需要通过ID来调用就好了。
下图从整体上描述了DLMS协仪模型协仪共分为3层,物理层,链路层,应用层 层与层之间使用指定的服务通讯,通讯的双方采用Client—Server结构,数据请求端(采集器)为Client,数据提供端(电表)为Server.
通讯过程描述:很好理解:建立三层的连接,然后再以此解除三层的连接
(一)建立物理层连接
物理层位于通讯模型的最底层 DLMS规约可以建立在多种物理层之上,物理 层的做用主要是对底层通讯硬件的操做(如对PSTN MODEM的初始化,打开, 关闭 ), 这个就是当我需要做什么操作的时候,如亮个灯那么我就需要把这个等做个初始化,这样的一般是都有驱动的,不用怎么考虑。
(二) 建立链路层连接
物理层连接建立之后,数据通讯的第一步是建立链路层的连接,链路层主要负 责数据传输的可靠性,包括以下几个方面,地址校验,帧长校验,数据的CRC校验 长数据帧的拆包组包 同时向应用层提供链路传输的服务,这个比较重要,有个数据链路的帧结构,挺麻烦的。后面详解。
(三)建立应用层连接
链路层连接建立之后,在DLMS协仪中还要建立应用层连接,才可进行数据通讯这个应用层连接建立过程被称为Negotioation,这个过程是为数据通讯提供一些配置参数应用层连接请求由Client端发起,Client端发aarq帧,Server端响应aare帧。
(四)进行数据通讯
当连接建立起后,就可进行数据通讯了 Client端发送数据请求帧Server端以数据响应 Client在请求不同的数据时,要使用特定数据的独有的class id和OBIS,用以标识不同类型的数据。这个跟698差不多。问题不大。
(五)数据通讯结束,释放链路,解除连接
数据通讯结束后,发链路结束帧,结束一次通讯过程 一次数据通讯结束后,可以通过发链路结束帧,来结束一次通讯过程 也可以,不发任何数据帧,依靠server端的超时挂断机制,来结束一次通讯过程 一般应使用前者
(六)解除物理层连接
关闭物理端口(如挂断Modem) 从物理上结束一次通讯
二、DLMS物理层协议
物理层协议位于DLMS协议族的最底层,负责数据通讯的物理传输 DLMS可以工作于多种不同的物理介质上(PSTN,网络,串行通道等),
物理层的功能是接受链路层数据,发送到物理介质上,传送到通信的对端 或是接收通信的对端传送来得数据,再传送到链路层,供更高层的协议处理数据
DLMS物理层协议,主要规定了物理层应实现的服务,如:打开端口,初始化端口,收发数据,关闭端口等 在通常的嵌入式系统中(如电能量采集装置),物理层对应于系统的底层驱动部分 这部分一般不被通讯规约控制 因此,在不影响通讯协议功能实现的前提下,本文将不具体讨论物理层服务
三、DLMS链路层协议
物理层之上即为链路层,链路层是物理层与应用层通信的通道 DLMS链路层使用的是HDLC高速链路控制协议
链路层的构成:
链路层由两个子层构成,即LLC子层,和MAC子层
(一)、LLC子层(逻辑链路控制子层)就一个转发作用。
这一层的功能是将MAC子层的数据转发到应用层,或将应用层的数据转发到MAC子层 LLC子层只是作转发而不对数据做出处理 其存在的重要性在于向应用层提供链路传输的服务(从链路层接收或发送数据)
具体到数据通讯时,对于client端应用层发送的数据,要加上LLC帧头(0xe6 , 0xe6, 0x00),server端应用层发送的数据,要加上LLC帧头 (0xe6 , 0xe7 , 0x00)
基本上都是0x7e开头。0x7e结束。
由于LLC子层链路传输服务的具体实现,可以不受DLMS协议的限制,由应用程序实现 故本文不具体说明LLC子层的各种服务
(二)、MAC子层(媒体访问控制子层)
MAC子层在链路层中负责数据传输的可靠性,包括地址检查,数据的CRC校验,长数据帧的打包拆包等 这些工作对于数据通讯都是必不可少的,MAC子层功能的说明将是以下的重点
1 HDLC帧格式
(1) 不包含应用层数据信息
0x7e 帧类型与帧长 目的地址域 源地址域 控制域 数据帧校验 0x7e
两个0x7e是HDLC数据帧固定的帧头与帧尾,两个0x7e之间是链用户数据
(2) 包含应用层数据信息
0x7e 帧类型与帧长 目的地址域 源地址域 控制域 帧头校验 LLC帧头 用户数据信息 数据帧校验 0x7e
与不包含应用层数据信息的数据帧相比这里多了3项:
帧头校验:为增强通讯的可靠性,对帧头的数据也加上CRC校验 帧头包括如下 字段:帧类型与帧长、目的地址域、源地址域、和控制域
LLC帧头:用户数据信息前要加0xe6 , 0xe6, 0x00或0xe6 , 0xe7, 0x00
用户数据信息:应用层处理的数据
注:出于数据完整性的考虑,用户数据信息的最大长度,默认为128字节 如果想要更多的字节,可以在SNRM数据帧中协议
2 帧类型字段与‘S’位
帧类型与帧长字段,共两个字节 内容如下:
如A0 0A:1010 0000 0000 1010
这个红色的1010,表示帧的类型一般默认是1010, 这个黄色的0,表示的是s位,就是看这个数据帧要不要分段。分段就是1,不分段就是0,剩下的11位都是帧长度的描述。所以一个帧最长就是2的11次方-1。
FrameType :用于指出当前数据帧的类型 HDLC有多种数据帧类型,DLMS使用Frame Type 3 FrameType恒为A(1010)
S:(segmentation Bit)这个字段只有一位,它用于说明数据帧是否被分割 在长数据帧传输时要使用到这一位 长数据帧的传输将在后面解释
FrameLength Sub-field :这个字段用于说明当前数据帧的长度,(以字节为单位,不包括两个0x7e)
3 地址解析
地址域分为两部分 目的地址域和源地址域 对于client端,目的地址为server的地址,源地址为client的地址 对于server端正好相反
(1) 扩展编址技术,
HDLC使用扩展编址技术,即某一个地址字节(意思就是8位里面最后一个是0,如0xb0, 1011 0000 最后一个就是零说明这个地没有读完)的最低位如为0,则表明该地址域没有结束,仍有后续字节是该地址域的一部分 若某一地址字节最低位为1,则说明该地址域已经结束,没有后续字节 ,
(2)地址结构
Client端的地址永远是一个字节,由于扩展编址技术的使用,最低位置1,所以client 端的地址只能有128个
Server端为了实现一个物理地址对应多个逻辑地址,将地址分成了两部分upper HDLCAddress 用于表述逻辑地址,lower HDLC address用于表述物理地址 Upper address总是应当有的,lower address在确认不需要的情况下,可以不出现 (sl7000 电表这两部分地址都是需要的)
Server端的地址在使用扩展编址技术时,也并非是可以无限长(虽然在理论上可以,但在实践上是有上限的) Server端的地址结构可以使用如下方式:
一字节:只出现HDLC高位一字节地址
两字节:只出现HDLC高位一字节地址,和HDLC低位一字节地址
四字节:只出现HDLC高位两字节地址,和HDLC低位两字节地址
这样看起来是非常形象的。
(3)特殊地址
有一些地址被HDLC定为保留地址 这其中比较重要的是广播地址
对于SL7000电能表,实践中可行的地址结构是client端一字节,server端4字节 对于DLMS协议族是可以使用上述地址结构中的任一种,并且支持特殊地址
4 帧控制字
帧控制字字段主要负责,通讯中的帧计数,以及特殊数据帧的标识
帧控制字字段结构如下:
对应项的解释如下:
RRR:为接收帧计数
SSS:为发送帧计数
注:对帧计数的解释,,只对帧来计数,那些响应数据不算的。但是传输的不都是帧的方式吗,?,好像这个帧计数是针对客户端的吧?
在链路层连接建立之后,第一次请求数据时(在client端,包括发送AARQ) RRR置为0,SSS置为0, Server端收到这一帧数据后,返回数据响应RRR为1,SSS为0 ,Client再次请求数据时RRR目前是1,SSS加1, Server端收到这一帧数据后,返回数据响应(也就是client接收到了)RRR加1(成为2),SSS加1 如此反复直到client得到所有的数据为止 整个数据传输过程以I数据帧请求和响应 ,这里要说明的是在请求数据结束后还要再发送RR帧,收到确认后 才可以再发送DISC帧结束链路(就好像我们不聊天了,我还要发一个说我没有话题,你也别说话了。这个就是RR帧) 其中Client端的RR帧中的帧计数位RRR只需将client的帧计数位RRR加1得到下图描述了帧计数位的变化过程:
P/F:poll/final bit //轮询/停止。
Poll bit :由client发送,置1时表示server端回应,置0时表示不允许回应
听他这意思,好像是只有客户端才能轮询(查询)服务器是不能的
反过来服务器只能结束,不能查询
final bit:由server发送,置1时表示一次数据帧的发送结束,置0时表示还未发送完, final bit只有在通讯窗口(window size)大于1的情况下才有意 义 在window size = 1时,由server端返回的数据帧中的这一位总是 置1 (关于window size将会在“建立链路层连接”时解释)
他这通信窗口可以理解为只能允许发送多少个字节的数据,如果等于一,根本不用你来说什么时候结束,她自然到了1就结束。 当很大的范围的时候我才要考虑什么时候来停止。
几种不同的数据帧分别应用在不同的场合,下图列出了几种请求和响应的对应的情况 , 这个好像是对应着来的。
I :信息传输帧,里面就包含RRR/SSS就是计数的。
RR :准备接收数据帧(用来表示准备接收下一帧数据)
RNR:接收没有准备好(receive not ready) 相当于别的通讯协议中的忙帧
SNRM:设置正常相应数据帧 用于建立链路层连接
UA:对SNRM和DISC的响应帧
DISC:结束链路帧
DM:对DISC的响应帧 (Disconnected mode)
UI:可以用于保持链路,这个数据帧的发送,对于链路的控制没有任何影响
FRMR:拒绝接收帧(Frame reject),由于不确定的某种原因拒绝接收到的数据帧
这里RRR是接收序列号N®,SSS是发送序列号N(S),P/F是查询/结束位。
链路层链接好即SNRM UA帧后(链路层搭建好了后),RRR和SSS均为000,发送一帧I帧(信息帧)SSS加1,接收到一帧I帧(信息帧)RRR加1,客户端和服务端都是如此。P/F标志位中P是对客户端而言的,需要响应P=1,那么广播帧时P=0;F是对服务端而言的,F表示发送是否结束,也就是是不是没有后续帧,F=1表示有后续帧,因此当客户端收到服务端发送来的帧格式域中S=1和此处的F=1的帧时,需回应RR帧等待接收未接收完的数据。
OBIS码 的介绍。详见IEC62056-61
其大概的功能就是类似于OAD一样表示什么正向有功啊什么的等等。
OBIS码是一个由6个数码组构成的组合编码,它以分层的形式描述了每个数据项的准确含义,见图1。 假设数码是:01 01 01 08 00 ff
A B C D E F
01 01 01 08 00 ff
数值组A
数值组A定义了所要标识的数据项(抽象数据,电-、气-、热-、水-相关数据)的特性。 就是看是什么类,这个01就是表示是电表
数值组B
数值组B用于定义通道号,既计量设备的输入编号,计量设备具有多个测量相同或不同类型能量的输入通道(例如:数据集中器或记录单元),其不同来源的数据因此可以得到标识。本数值组的定义与数值组A相互独立。 01就是通道一数值组B的范围为1至255(见表2)。
表2 数值组B代码
数值组B
0 无指定通道
1 通道1
… …
64 通道64
65…127 保留
128…254 制造商特定代码
255 保留
实现时如果仅有一个通道,即便是非指定通道数据也可以指定为通道1。
数值组C
数值组C定义了与信息来源相关的抽象或物理数据项,例如:电流、电压、功率、容积、温度,这些定义取决于数值组A中的值(如果A=0,就是抽象数据,A=1就是一些电表数据,)。这些量的测量方法、费率处理和数据存储方法是由数值组D、E和F进行定义。对抽象数据,这种6个数码域的分层结构是不适用的。
数值组C的范围为0至255(见表3针对A=0和表4针对A=1)。
数值组D
数值组D用于定义类型,或者由数值组A和C所标识的物理量按各种特定的算法处理的结果,这些算法可计算出能量和需量,以及其它物理量。
数值组E
依照所使用的费率,数值组E用于定义对由数值组A到D标识的测量结果所做的进一步处理,对于抽象数据和与费率无关的测量结果,本数值组可以进一步分类。
如果是下列数值组E应用说明之一,则上表是无效的
数值组F
数值组F用于定义由数值组A到E标识的不同计费周期的数据存储。对与此无关的数据,本数值组可以进一步分类。数值组F的范围为0到255。
在任何情况下,如果数值组F没有被使用,则它被设置为255.
1.1.1 数值组F用于计费周期
对于含有下列代码的对象,数值组F规定了不同的收费周期的位置(历史数值集合):
数值组A:1
数值组C:1至99
数值组D:0至3 ;6;8至13;16;21至23;26
当0≤F<100时这个位置有效。见表10。
5 长数据帧的传输
在很多情况下,数据不能在一次请求和一次响应中,就能够结束数据传输的过程(受限于用户数据字节不超过128字节) 这时就有必要启动长数据帧链路控制流程
注:请求负荷曲线时一定是使用长数据帧
当使用长数据帧时,必须把长数据帧分割成短数据帧 然后把这些短数据帧依次发送出去,在接收端将这些短数据帧依次处理 这样就实现了一个较大的数据包,完整的传送到接收端
在数据帧被分割时,帧类型与帧长字段中的‘S’位,将被置1 当接收端检测到这一位被置位后,就知道数据帧已被分割,此时要做出对分割数据帧的相应处理
下图介绍了长数据帧的收发过程:
client端通过发送RR数据帧(准备接收下一数据帧)来请求被分割的数据帧的其他部分。
6 HDLC数据帧校验
HDLC使用16位CRC校验 (crc16这个网上有代码) 使用的多项式是:
具体的实现程序,可参照英文参考文献IEC62056 - 46的附录A
(三)、链路层连接的建立,与断开
(1)建立连接
链路层在开始工作之前,要建立链路层连接(Association) 这一步骤是通过client端发送SNRM数据帧(设置正常的链路连接)0,server端响应UA数据帧表示已建立连接(响应了表示连接成功了),server端响应DM数据帧表示链路断开,连接没有建立(DM表示不得行)
UA数据帧常含有链路参数的配置信息 链路参数是指2个控制数据传输的参数
WINDOW_SIZE parameter;这个就是上文提到的窗口的大小,这个参数描述通讯时,通讯的双方一次发送数据帧的数目(所以size=1的话一次发送一个确实没有必要设置final=1,表示发完了。),HDLC允许一次发送多帧数据
MAXIMUM_INFORMATION_FIELD_LENGTHparameter . 最大信息域长度,这个参数用于描述一个链路数据帧中用户数据的长度 。
这两个参数的默认值如下
default WINDOW_SIZE = 1;
defaultMAXIMUM_INFORMATION_FIELD_LENGTH = 128(BYTEs)
具体在数据帧中有如下4个参数:
transmit maximum information field length 发送的信息域最大的长度
receive maximum information field length 接收的信息域最大的长度
transmit window size 发送窗口大小
receive window size 接收窗口大小
注:这里没有给出数据帧的具体格式,而是用举例来说明如何组帧 这种做法可能给读者带来不便 但在DLMS的规约原文中就是用这种办法,故这里仍这样做 醉了。还有这操作
以下举例说明如何建立连接:
(1)SNRM,建立链路层的连接
。这个帧是很奇葩的。里面规定的以后怎么传输数据的格式。
S: 7e a021 00 22 00 23 03 93 0b 14 81 80 12 05 01 80 06 01 80 07 04 00 00 00 01 08 0400 00 00 07 65 5e 7e
这里的SNRM:100P 0011, 当P=1(要响应)时控制域就是93,跟本例子符合啊。
解释:
7e 起始字符
a0 21 帧类型、“S”与帧长
00 22 0023 目的地址因为3是11,最后一个是0,表示地址结束。
03 源地址,同上理
93 控制字,控制域的意思。
0b 14 帧头校验, crc16校验的。网上有示例代码。
81 80 SNRM 标识, 这个怎么来的还不懂?
S: 7e a021 00 22 00 23 03 93 0b 14 81 80 12 05 01 80 06 01 80 07 04 00 00 00 01 08 0400 00 00 07 65 5e 7e
12 group lenth. 群长度 12=0001 0010 = 18字节,规定后面有18个字节的。
05 H parameter identifier (maximum information field length transmit)
参数标识符(最大信息字段长度传输)
01H parameter length (1 octet)一字节。
参数长度
80H parameter value(128 bytes),
参数值1000 0000 = 2的7次方128.
06H parameter identifier (maximum information field length receive)
最大信息字段长度接收
01H parameter length (1 octet)
参数长度,
80H parameter value (128 bytes)这个有点像
接收的信息域最大的长度
参数值, 1000 0000 = 2的7次方128.
07H parameter identifier (window size, transmit)
传输的窗口大小。
04H parameter length (4 octets)
是4个字节,后面就有4个字节,是高位在前低位在后
00H parameter value (high byte of value)
值的高字节
00H parameter value
00H parameter value
01H parameter value (low byte of value)
值的低字节
08H parameter identifier (window size, receive)
接收窗口大小
04H parameter length (4 octets)
是4个字节,后面就有4个字节,是高位在前低位在后
00H parameter value (high byte of value)
00H parameter value
00H parameter value
07H parameter value (low byte of value)
65 5e 数据帧校验(CRC校验)
7e
在SNRM数据帧中的用户信息可以不出现,表示client接收server端的已配置数据
//UA
R: 7E A021 03 00 22 00 23 73 28 F0 81 80 12 05 01 80 06 01 80 07 04 00 00 00 01 08 0400 00 00 01 53 3B 7E
解释:
7E//Flag
0xA0 21 //(type=a :frame type 3 , s=0 :end of frame , len=021 : 33 bytes是除了flag的33个字节。)
03 //source address, 目标地址,
一看就知道是一个客户端的地址,只有一个字节。。
00 22 00 23 //destination address ,原地址,服务器地址。跟上面是对应的。
73 //control UA
UA=73表示 0111 0011 ,那么F=1表示还没有结束。还有后续帧
28 F0 //hcs crc16校验就是校验前面的除了7e的数
81 80 12 05 01 80 06 01 80 07 04 00 00 0001 08 04 00 00 00 01
//information field 信息域
//parameter negotiation 参数协商
//81 80 SNRM 标识, 跟上的上面的对应的。
//12 0001 0010=16+2, 18个字节, 这个12后面刚好18个字节
//05 01 80 :maximuminformation field length transmit (128BYTEs) 跟上面一样的
//06 01 80 :maximuminformation field length receive (128 BYTEs)
//07 04 00 00 00 01 :window size,transmit (1)
//08 04 00 00 00 01 :window size,receive (1)
53 3B//fcs
7E
上面就是建立连接。
(2) 断开连接
断开连接由于不用参数设置,所以比建立连接要简单 Client端发送DISC数据帧,Server端响应UA或DM表示断开连接。 UA表示接到DISC后断开连接 。DM表示在接到DISC之前已处于断开状态 。
原来这个一切都是有迹可循啊。跟下面这个图有关系。
一下仍给出具体的通讯实例:
S: 7e a0 0a 00 22 00 23 03 53 06 c7 7e
解释:
7e a0 0a 00 22 00 23 03
目标地址 源地址,:可以看出是一个客户端发给服务器的断开连接的帧。
53 // 帧类型Disc,表示P是1,可以接受响应。
06 c7 校验
7e 结束
R: 7E A0 0A 03 00 22 00 23 1F 43 4C 7E
解释:
7E A0 0A 03 00 22 00 23
1F//帧类型DM 表示F=1帧还未停止,后面还有???,这个有点迷为啥F不是=0???解释好像是这样意思:
F=1表示有后续帧,因此当客户端收到服务端发送来的帧格式域中S=1和此处的F=1的帧时,需回应RR帧等待接收未接收完的数据。
43 4C 7E
(四)、关于链路层的透明数据传输HDLC
0x7e 帧类型与帧长 目的地址域 源地址域 控制域 帧头校验 LLC帧头 用户数据信息 数据帧校验 0x7e
HDLC是一种透明数据传输的链路层协议 用户数据信息与链路层没有任何关系 在DLMS的协议模型中,链路层负责数据传输的可靠性,应用层处理用户数据信息 ,链路层为应用层数据的传输提供透明通道。
透明传输:透明数据传输是指:上位机与模块进行信息交换的数据格式,没有像指令字头、结束符等数据包信息,只要上位机串口有数据输出,模块就把串口的数据以无线方式编码发送,当接收模块接收到发射模块发送的无线数据信号后进行解码,把解码后的数据按发送端的格式从串口输出。也就是说模块对使用者是开放的,透明的,实际上,在点对多点的组网通信中,我们完全可以将无线数据透明传输方式等同于有线连接的总线方式。不同点是无线连接方式存在较大延时。透明传输是指数据直接通过系统中的互连功能模式而不进行RLP纠错,如果进行了RLP纠错即为非透明传输。不管传的是什么,所采用的设备只是起一个通道作用,把要传输的内容完好的传到对方!
四、DLMS应用层协议
理解DLMS应用层协议,需要首先建立以下几个概念:
ASN.1语法,BER编码,AXDR编码 三大拦路虎
ASN.1语法是用来描述应用层数据帧的 DLMS协议不同于其他一些简单通讯协议的地方就在于此 他不是用一些表格,及一些固定的帧格式来描述的,而是用一种抽象语法语言来描述 这样做的好处是,极大的提高了协议的抽象性和通用性,有利于程序移植。跟那个698差不多,就是一大堆对于的关系,什么日冻结,,,
BER编码和AXDR编码是用来实现ASN.1语法的 为了实现ASN.1的抽象性和通用性,这个语法要用特殊的编码来描述 这就引入了BER编码和AXDR编码
以下分别解释这几项
(一)ASN.1语法
一个用ASN.1语法描述的数据帧,看上去应该是下面的样子:
Name ::= [tag] IMPLICIT/ EXPLICIT Data type
{
null-data [0] IMPLICIT NULL,
item1 [1] IMPLICIT/ EXPLICIT Data type A1 OPTIONAL
item2 [2] IMPLICIT/ EXPLICIT Data type A2 OPTIONAL
item3 [3] Data type
…
}
下面解释这个语法描述
Name - 是这个数据帧的名字
Tag - tag包含两部分classtype 和一个数字
Class type类的类型有以下四种:
1)Universal 通用的表明name定义的数据帧在所有的DLMS应用中的含义是唯一的,大家都这么用你不能乱改。
2)Application 应用表明name定义的数据帧的含义同具体的应用有关 。
3)Private 表明name定义的数据帧只在某一厂家的自定义范围之内 。
4)Context-specific 表明name定义的数据帧同上下文数据项的含义有关,这种类型的数据,在不同的结构中可能有不同的含义。
Tag中的数字,是作为这个数据帧的标号存在的,它做为该数据帧的句柄出现,在应用数据单元APDU中。
IMPLICIT/ EXPLICIT - 隐式/显式当前数据帧(称为子数据帧)可能派生于某一数据帧(称为父数据帧),这个字段用来描述子数据帧同父数据帧的关系
IMPLICIT : 改变了父数据帧的Tag - 跟你爸不一样都隐藏了
EXPLICIT : 不改变父数据帧的 Tag - 跟你爸一样的都看出来了
不注明IMPLICIT的项即为EXPLICIT
Data type-描述数据帧的数据类型, 数据类型分为简单型和复合型, 多数数据类型可以从名字看出其类型 以下列出了几种,完整的数据类型集合请参见附录
Type Tag number Tag number
(decimal十进制) (hexadecimal十六进制)
INTEGER 2 02
BIT STRING 3 03
OCTET STRING 4 04
NULL 5 05
OBJECT IDENTIFIER 6 06
SEQUENCE and SEQUENCE OF 16 10
SET and SET OF 17 11
PrintableString 19 13
T61String 20 14
IA5String 22 16
UTCTime 23 17
“{}”- 大括号中的内容,即为数据帧中的数据项 ,每一数据项后的数字序号,即为该数据项的标识(tag)(这个就跟那个698里面data里面的类型) 每一数据项可以是对另一数据帧的复合,即一个数据帧通常是对其它数据帧的一种组合 。
OPTIONAL-这个关键字描述的数据项,在用户认为不需要的场合可以省略。
比较重要的两种复合类型
SEQUENCE(序列)和CHOICE(选择)
下面举例解释:
1)SEQUENCE : 数据帧中的内容是顺序排列的 下面以举例说明SEQUENCE类型
Get-Request-Normal ::= SEQUENCE
{
invoke-id-and-priority Invoke-Id-And-Priority,
cosem-attribute-descriptor Cosem-Attribute-Descriptor,
access-selection-parameters Selective-Access-DescriptorOPTIONAL
}
这是一个在请求数据时常用的数据帧 SEQUENCE表明数据帧的内容是顺序排列的
2)CHOICE :即选则类型,它表明当前数据帧是从几个数据帧中选择一种做为当前数据帧的类型 下面以举例说明CHOICE类型
GET-Request ::= CHOICE
{
get-request-normal [1] IMPLICIT Get-Request-Normal,
get-request-next [2]IMPLICIT Get-Request-Next,
get-request-with-list [3] IMPLICIT Get-Request-With-List
}
GET-Request数据帧只能填入三个选择项之一 (来了,跟698相似的)
以上简单介绍了ASN.1语法,由这一语法描述的各种数据帧,将在附录中全部给出 这些各种各样的数据帧,将构成DLMS协议中Client同Server应用层交互时使用的语言 。
读者如对ASN.1语法有不解之处,可参阅本文的英文参考文献【7】
(二)BER编码与AXDR编码
ASN.1只是一种语法,要把它写入数据帧中,就要把它转换为一个个数据字节 这就要一种(实际是两种)编码来实现这种语法,于是就引入了BER编码与AXDR编码。就好像C语言和汇编的感觉。
在DLMS中用ASN.1描述的DLMS协议,用BER编码实现;用ASN.1描述的XDLMS协议用AXDR编码实现
注:DLMS中只有AARQ与AARE数据帧的部分内容是使用DLMS协议的 ,绝大多数的应用层数据通讯使用XDLMS 这里无意对DLMS和XDLMS做出划分和解释,具体的解释可参见英文参考文献【2】 这里只需知道这两种协议使用不同的编码
1 BER
编码的详细语法参见附录
通常的BER编码采用如下结构,其中数据内容部分可以嵌套另一BER编码结构:
数据标识 数据长度 数据内容
数据长度,和数据内容从名字即可啥意思。
这里有必要解释一下数据标识的构成:
一个BER数据标识和一个BER数据长度构成一个16位的位串:总共2个字节。
bit15 bit0
datatype classes(bit15、14) Data type(bit13) data length(bit12-bit0)
1)datatype classes 字段:这一字段用于对ASN.1语法中的class type编码
Universal (00)
Application (01)
Context-specific (10)
Private (11), 这个就是看看这个类是什么类。
2)Datatype字段:用于描述数据内容的结构
Primitive (0) 简单类型
Constructed (1) 复合类型(数组array或结构struct)
3)datalength字段:用于描述数据内容的长度(以字节为单位)
下面以接收到的AARE数据帧为例:
链路层连接建立之后,在DLMS协仪中还要建立应用层连接,才可进行数据通讯这个应用层连接建立过程被称为Negotioation,这个过程是为数据通讯提供一些配置参数应用层连接请求由Client端发起,Client端发AARQ帧,Server端响应AARE帧。
AARE数据帧的语法描述:
AARE - apdu ::= [APPLICATION1] IMPLICIT SEQUENCE
应用程序隐式序列
――[APPLICATION 1] == [ 61H ] = [ 97 ]
{ 0x61=0110 0001=32+64+1=97;
protocol-version (协议版本) [0] IMPLICIT BITSTRING {version1 (0) } DEFAULT{version1}default默认。,
application-context-name [1]Application-context-name,应用上下文名称
result [2] Association-result,关联结果
result-source-diagnostic [3] Associate-source-diagnostic, 关联源诊断,
responding-AP-title [4] AP-title OPTIONAL, 他这个可选的意识是不是开始按照上面的规则一步一步来,后面可以选了。就可以选择自己要那个OPTIONAL
responding-AE-qualifier [5] AE-qualifier OPTIONAL,
responding-AP-invocation-id [6] AP-invocation-identifier OPTIONAL,
responding-AE-invocation-id [7] AE-invocation-identifier OPTIONAL,
– The following field shall not be presentif only the kernel is used.
responder-acse-requirements [8] IMPLICIT ACSE-requirements OPTIONAL,
– The following field shall only be presentif the authentication functional unit is selected.
mechanism-name [9] IMPLICITmechanism-name OPTIONAL,
– The following field shall only be presentif the authentication functional unit is selected.
responding-authentication-value [10] EXPLICIT authentication-value OPTIONAL,
implementation-information [29] IMPLICIT implementation-dataOPTIONAL,
user-information [30]IMPLICIT association-information OPTIONAL
} 这个看不懂。直接看下面的实际举例子。
AARE数据帧的BER编码和AXDR编码实现:
61 //AARE tag
42 //AARE len
A1 //tag of COSEM_Application_Context_Name
09 //数据长度
06 //(OBJECTIDENTIFIER, Universal)OBJECT IDENTIFIER是对象标识符。 //ASN.1数据类型.
07 //数据长度
60 85 74 05 08 01 01 //数据内容, 七个字节
//以下的数据帧可以用同样的方法一一解释
A2 //Tag of Association-result,
03 02 01 00
A3 //Tag of Associate-source-diagnostic
05 A1 03 02 0100
88 //IMPLICIT ACSE-requirements OPTIONAL
02 07 80
89 //IMPLICIT mechanism-name OPTIONAL
07 60 85 74 05 08 02 01
AA //EXPLICIT authentication-value OPTIONAL
0A 80 08 41 42 43 44 45 46 47 48
BE
04 // encoding the choice for user-information (OCTET STRING,Universal)
对用户信息的选择进行编码(八进制字符串,通用)
0E // encoding of the length of the OCTET STRING’s value field (14 octets)
八位字节字符串值字段长度的编码(14个八位字节)
/以下内容为XDLMS用AXDR描述/
08 //encoding the tag (explicit tag) of the DLMS PDU
对DLMS PDU的标记(显式标记)进行编码
CHOICE(InitiateResponse)
00 // usage flag for the proposed-quality-of-service component(FALSE, not present)
建议的服务质量组件的使用标志(FALSE,不存在)
06 //negotiated-dlms-version-number 协商的dlms版本号
5F 1F // encoding the [APPLICATION 31] tag (ASN.1 explicit tag)
编码[APPLICATION 31]标记(ASN.1 explicit tag)
04 // encoding the length of the ‘contents’ field in octet (4)
编码“contents”字段的长度(八位字节)(4)
00 // encoding of the number of unused bits in the final octet ofthe bitstring
位串最后一个八位字节中未使用位数的编码
00 08 1D// encoding of the fixed length BITSTRING value
21 34 // the A-XDR encoding of an Unsigned16 is its value
0007 // the A-XDR encoding of an Unsigned16 is its value . 00 07 == LN
2 A-XDR:
这种编码是对unix的XDR(外部数据标识法)编码的扩展 参见IEC61334采用配线载波的配电自动化,译文汇编,下册,第六部分 本文参考文献【9】
3 两种编码的比较:
A-XDR编码,与BER编码的区别可从下例看出
对两数进行编码,其值分别为0x1234,0x5678
1) 用BER编码
30 08 02 02 12 34 34 02 56 78
序列标识 30
序列长度 08 表示后面有8个字节
A的标识(整型) 02
A的字长 02
A的数值 12 34
B的标识(整型) 34
B的字长 02后面有两个字节
B的数值 56 78
A-XDR编码,与BER编码的区别可从下例看出
对两数进行编码,其值分别为0x1234,0x5678
2) 用AXDR编码
1 12 34 56 78
序列标识 01
A的数值 12 34
B的数值 56 78
但是他怎么知道什么是A的数,什么是B的数。
这里给出一个AXDR编码的实例:
注:这里的语法仍是ASN.1但将采用不同的编码
ASN.1语法描述:(这一数据帧是AARQ数据帧的一部分)
xDLMS-Initiate.request ::= SEQUENCE
{
dedicated-key OCTET STRINGOPTIONAL, 可以选择用不用
response-allowed BOOLEANDEFAULT TRUE,
proposed-quality-of-service[0] IMPLICIT Integer8 OPTIONAL,
proposed-dlms-version-numberUnsigned8,
proposed-conformanceConformance,
client-max-receive-pdu-sizeUnsigned16
}
AXDR编码:
01--------------------------------------------------------dlmspuu标识
00 ----------------------------------//usageflag for the dedicated-key component (FALSE, not present) 专用密钥组件的usageflag(FALSE,不存在)
00--------------- //usage flag for theresponse-allowed component (FALSE, default value conveyed) 响应允许组件的用法标志(FALSE,默认值)
00-------------- //usage flag for theproposed-quality-of-service component (FALSE, not present) 建议的服务质量组件的使用标志(FALSE,不存在)
06-------------- //the A-XDR encoding of anUnsigned8 is its value
anUnsigned8的A-XDR编码是它的值
5f ---------- //encoding the [APPLICATION31] tag (ASN.1 explicit tag)
编码[APPLICATION31]标记(ASN.1显式标记)
04---------- //encoding the length of the’contents’ field in octet (4)
用八位字节(4)编码“contents”字段的长度
00-----//encoding of the number of unused bits in the final octet of the BITSTRING/位串最后一个八位字节中未使用位数的编码
00 00 10------- // encoding of the fixedlength bitstring value.(LN/SN)
固定长度位字符串值的编码。(LN/SN)
00 80 // client-max-receive-pdu-size(128 bytes)客户端最大接收pdu大小(128字节)
(三)AARQ与AARE数据帧
有了基本的语法和编码的概念后,下面就开始讨论具体的DLMS应用层协议 在前面的DLMS协议模型中已经说明,在进行应用层数据通讯之前,要建立链路层连接和应用层连接 链路层连接已经在链路层协议中解释过,下面讲如何建立应用层连接
应用层连接的建立是通过client端发送AARQ数据帧,server端响应AARE数据帧来实现的 这两个数据帧主要是配置应用层数据通讯的参数
关于AARQ,AARE:
在标准的面向连接的应用层服务控制(ACSE)中,为了同服务的使用者进行交互,ACSE提供了很多功能单元 在COSEM中只使用了其中的两个:the kernel and theauthentication functional units. 内核和验证功能单元。
(一) AARQ , AARE数据帧的具体描述(ASN.1语法描述):
AARQ-apdu ::= [APPLICATION0] IMPLICIT SEQUENCE
{
protocol-version [0] IMPLICIT BIT STRING{version1 (0) } DEFAULT{version1},
application-context-name [1] Application-context-name,
called-AP-title [2] AP-title OPTIONAL,
called-AE-qualifier [3] AE-qualifier OPTIONAL,
called-AP-invocation-id [4] AP-invocation-identifier OPTIONAL,
called-AE-invocation-id [5] AE-invocation-identifier OPTIONAL,
calling-AP-title [6] AP-title OPTIONAL,
calling-AE-qualifier [7] AE-qualifier OPTIONAL,
calling-AP-invocation-id [8] AP-invocation-identifier OPTIONAL,
calling-AE-invocation-id [9] AE-invocation-identifier OPTIONAL,
. Thefollowing field shall not be present if only the kernel is used.
. sender-acse-requirements [10]IMPLICIT ACSE-requirements OPTIONAL,
– The following field shall only be presentif the authentication functional unit is selected.
mechanism-name [11] IMPLICIT mechanism-nameOPTIONAL,
– The following field shall only be presentif the authentication functional unit is selected.
calling-authentication-value [12] EXPLICIT authentication-value OPTIONAL,
implementation-information [29] IMPLICIT implementation-data OPTIONAL,
user-information [30] IMPLICITassociation-information OPTIONAL
}
AARE-apdu ::= [APPLICATION1] IMPLICIT SEQUENCE
{
protocol-version [0] IMPLICIT BITSTRING {version1 (0) } DEFAULT{version1},
application-context-name [1]Application-context-name,
result [2] Association-result,
result-source-diagnostic [3] Associate-source-diagnostic,
responding-AP-title [4] AP-title OPTIONAL,
responding-AE-qualifier [5] AE-qualifier OPTIONAL,
responding-AP-invocation-id [6] AP-invocation-identifier OPTIONAL,
responding-AE-invocation-id [7] AE-invocation-identifier OPTIONAL,
– The following field shall not be presentif only the kernel is used.
responder-acse-requirements [8] IMPLICIT ACSE-requirements OPTIONAL,
– The following field shall only be presentif the authentication functional unit is selected.
mechanism-name [9] IMPLICITmechanism-name OPTIONAL,
– The following field shall only be presentif the authentication functional unit is selected.
responding-authentication-value [10] EXPLICIT authentication-value OPTIONAL,
implementation-information [29] IMPLICIT implementation-dataOPTIONAL,
user-information [30]IMPLICIT association-information OPTIONAL
}
被标记为OPTIONAL的项,在组成数据帧时都是可以被省略的
但有如下几个例外:
(1) user-information携带着XDLMS信息(XDLMS将在稍后解释),是永远不能被省略的
(2) 如Server端声明了身份校验(要求提供密码登陆),则AARQ中的sender-acse-requirements,mechanism-name,calling-authentication-value,AARE中的responder-acse-requirement,mechanism-name ,responding-authentication-value 都是不能被省略的 如果省略这些项,则请求数据将被拒绝。 就是服务器要你输入密码和账号你不输入,那你久登录不上去。
(二)AARQ , AARE数据帧中各项的解释:
1 AARQ
protocol-version: 即 ACSE protocol-version. 使用默认值在数据帧中不出现
application-contex-name:这项是必须项,对于目前的使用情况这个值是唯一的 (0x60 0x85 0x74 0x050x08 0x01 0x01,具体含义不解释了,可参见IEC62056-53 的7.3.7.1)
sender and responder acse requirements: 发送方和响应方acse要求,指明是否使用ACSE authentication功能(请求数据等),使用BER位串编码,只使用BIT0位该位置位时表明使用authentication身份验证功能。
例:
8a // the tag for the acse-requirements field component ([10],IMPLICIT, Context-specific ) acse需求字段组件的标记([10],隐式,上下文特定)
02 //Len
//the sender-acse-requirements component (ACSE-requirements::= BIT STRING) 发送方acse需求组件(acse需求::=位字符串)
07 //the number of unused bits in the last byte of the BITSTRING
//位字符串最后一个字节中未使用的位的数目
80 //encoding of the authentication functional unit (0) 最高位置1其余的为unused bits 认证功能单元的编码(0)
mechanism-name:用于指明使用何种Authentication 共有4种身份验证
calling and authentication value: 指出Authentication的值(即密码)
user-information: 内容即为xDLMS-Initiate.requestPDU,xDLMS-Initiate.request的内容如下 开始请求
xDLMS-Initiate.request :: = SEQUENCE
{
dedicated-key OCTET STRING OPTIONAL,
response-allowed BOOLEAN DEFAULT TRUE,
proposed-quality-of-service [0] IMPLICIT Integer8 OPTIONAL,
proposed-dlms-version-number Unsigned8,
proposed-conformance Conformance,
client-max-receive-pdu-size Unsigned16
}
下面分别解释xDLMS-Initiate.request的各项内容:
dedicated-key :指出数据是否被加密(ciphering) 通常不用
response-allowed :是否允许回应 通常允许
proposed-quality-of-service:通常不用
proposed-dlms-version-number:目前是6
proposed-conformance :这是主体部分,主要描述需要server端提供的XDLMS服务类型和种类
它是一个24位的位串,如上图所示,每一位都代表一种服务,具体解释如下:
Attibute_0 referencingwith SET is not supported (Bit_08)
Priority Management issupported (Bit_09)
Attibute_0 referencingwith GET is supported (Bit_10)
Block Transfer with theGET service is supported (Bit_11)
Block Transfer with theSET service is supported (Bit_12)
Block Transfer with theACTION service is supported (Bit_13)
Multiple references aresupported (Bit_14)
All LNservices (GET, SET, ACTION,EVENT NOTIFICATION) are supported (Bit_19, 20, 22,23)
Selective Access featureis supported (Bit_21)
这里提供的多种服务,对于采集器抄表来说,对于采集器最重要的服务是GET service,即读取数据的功能 通常这个24位的位串被定义为0x00,0x00,0x10即可 即只使用LN services的GET service
client-max-receive-pdu-size:client端接受数据的最大限制 设为0x0000 表明使用默认设置,则应用层数据单元最长为128字节
例:
以下为接受到的一个最长数据单元
R:
7E A8 8C 03 00 22 00 23 BA 88 4D //HDLC 帧头
起始。帧类型,目标地址,源地址,控制域,HCS.
00 00 00 02 02 0F 00 16 1E 02 03 09 06 01 01 3E 08 00 FF 06 00 00 00 00 02 02 0F 00 16 1E
02 03 09 06 01 01 02 08 00 FF 06 00 4B 09 74 02 02 0F 00 16 1E 02 03 09 06 01 01 17 08 00 FF 06 00 00 7E 72 02 02 0F 00 16 20 02 03 09 06 01 01 2B 08 00 FF 06 00 00 01 2C 02 02 0F 00 16 20 02 03 09 06 01 01 3F 08 00 FF 06 00 00 00 00 02 02 0F 00 16 20 02 03 09 06 01 01 03 08 00 FF 06 00 00 7F //应用层数据单元128字节APDU刚好128个。
2A EA 7E //HDLC帧尾
(
(IMPORTANT For compliance with existing implementations, encoding ofthe [Application 31] tag on one byte (5F),instead of two bytes (5F1F) is accepted when the 3-layer, connection-oriented, HDLC based profile isused.)
对于符合现有实现非常重要,[Application 31]标记的编码为一个字节(5F)当使用3层、面向连接、基于HDLC的配置文件时,不接受两个字节(5F1F)
2 AARE, 服务器发出来的。
protocol-version: 即 ACSE protocol-version. 使用默认值在数据帧中不出现
result: Server端对于Client端的连接请求回复的结果
result-source-diagnostics: Server端拒绝Client端的连接请求,在这里给出原因
application-context-name: 同AARQ
responding authentication value: 同AARQ
user-information: 内容即为xDLMS-Initiate.responsePDU,xDLMS-Initiate.response的内容 如下
xDLMS-Initiate.response :: = SEQUENCE
{
negotiated-quality-of-service [0] IMPLICIT Integer8 OPTIONAL,
negotiated-dlms-version-number Unsigned8,
negotiated-conformance Conformance,
server-max-receive-pdu-size Unsigned16,
vaa-name ObjectName
}
下面分别解释xDLMS-Initiate. response的各项内容:
negotiated-quality-of-service: 对应于xDLMS-Initiate.request的proposed-quality-of-service, 通 常不用
negotiated-dlms-version-number:对应于xDLMS-Initiate.request 的
proposed-dlms-version-number,目前是6
negotiated-conformance :这里是server端对client端请求的XDLMS服务的回应 如果允许client 端的请求,就对相应的位置1 位串的模式与 xDLMS-Initiate.request 的conformance相同
server-max-receive-pdu-size: server端可以接收的应用数据单元的最大限制 对于采集器而 言,通常不会向server端发送很长的数据帧
vaa-name : 目前此项没有什么用处,server端只是回应一默认值0x0007
3 其它项
AARQ,AARE数据帧中其它标为OPTIONAL的项,可以在数据帧中不出现,如果一旦在client端出现,而server端没有相应的处理,则server端只会把这些项略过,不作处理,而不会影响连接的建立。
也就是说,服务器如果没法处理这些项还可以不处理。略过,,,,感觉太智能了吧。
4 实例
这里给出一AARQ、AARE通讯实例
//aarq 客户端发起的。所以目标地址是服务器
S: 7e a047 00 22 00 23 03 10 d0 5e e6 e6 00 60 36 a1 09 06 07 60 85 74 05 08 01 01 8a 02 07 80 8b 07 60 85 74 05 08 02 01 ac 0a 80 08 41 42 43 44 45 46 47 48 be 10 04 0e 01 00 00 00 06 5f 1f 04 00 00 08 1d 00 00 9a 7a 7e
中间就是数据域。
解释:
{
7e 开始
a0 47 // 帧类型、S、帧长度。
00 22 00 23 // 目标地址
03 //源地址
10 //控制域
d0 5e //HCS校验
e6 e6 00 //LLC逻辑链路层。这个e6就很眼熟。
{
60 // AARQ tag作为AARQ的标识。
36 // length 0011 0110 ,,,不算自己54个字节。16+32+6=54
// Theapplication-context-name must be in. 应用程序上下文名称必须在中。
a1 //tag for theapplication-context-name component应用程序上下文名称组件的标记
09 //the length of the taggedcomponent value field 标记的零部件值字段的长度 7+2=9,下面就是len7 和 len2
06 // data type choice forapplication-context-name (OBJECT IDENTIFIER,Universal) 应用程序上下文名称的数据类型选择(对象标识符,通用)
07 // Len
60 85 74 05 08 01 01//(context_id = 1 ; means LN referncing);固定的。
//COMMENT by DL : The most important part of thisapplication-context-name //is that it chooses LN referencing or SN referencing.
这个应用程序上下文名称//最重要的部分是它选择LN引用或SN引用。
//encoding the sender-acse-requirementsfield component (tagged component, [10] 编码发送方acse要求字段组件(标记组件,[10] 上提到过
8a //encoding the tag for theacse-requirements field component
([10], IMPLICIT,Context-specific ) 编码ACSE需求字段组件的标记
([10],隐含,上下文特定)
02 //Len
//thesender-acse-requirements component (ACSE-requirements ::= BIT STRING) 发送acse要求组件(acse要求::=位字符串)
07 //the number of unusedbits in the last byte of the BIT STRING
位串的最后一个字节中未使用的位数
80 //encoding of theauthentication functional unit (0)
认证功能单元的编码(0)
//encoding theme chanism-name component (tagged component [11]) 编码主题机制名称组件(标记组件[11])
8b / //the tag for the mechanism-name component ([11], IMPLICIT,Context-specific)机制名称组件的标记([11],隐式,上下文特定)
07 //the length of the tagged component's value field标记组件的值字段的长度
60 85 74 05 08 02 01 //thevalue of the Object Identifier 对象标识符的值,跟上面的那个有点像
ac //the tag for the mechanism-name component ([12], Context-specific) 机制名称组件的标记([12],特定于上下文)
0a //Len
80 //the choice forAuthentication-information (charstring [0] IMPLICIT GraphicString)
08 //Len
41 42 43 44 45 46 47 48
/* User information can't beignored. *//*无法忽略用户信息*/
be //user information(x-DLMS context) /用户信息(x-DLMS上下文)
10 //Len (according to bytes) /Len(按字节) 16个
{
04 //data type choice foruser-information (OCTET STRING, Universal) 用户信息的数据类型选择(八进制字符串,通用)
0e //Len = 14 bytes后面14个字节
01 00 00 00 06 5f 1f 04 00 00 08 1d 00 00
//the octet sequence of the xDLMS-Initiate.requestPDU. /xDLMS-Initiate.requestPDU的八位字节序列。
/*
xDLMS-Initiate.request:: = SEQUENCE
{
dedicated-key OCTETSTRING octet string .OPTIONAL,
response-allowed BOOLEAN 布尔值默认是真,DEFAULTTRUE,
proposed-quality-of-service [0] IMPLICIT Integer8 OPTIONAL, 隐式整数8可选,
proposed-dlms-version-number Unsigned8,整数8
proposed-conformance Conformance, 一致性,
client-max-receive-pdu-size Unsigned16 整数16位
}
Theclient-max-receive-pdu-size is 1200D = 0x4B0.
/
/
01 //the tag (explicit tag)of the DLMS PDU CHOICE
//–dedicated-key //DLMS PDU选项的标记(显式标记)
//–专用钥匙
00 //usage flag for thededicated-key component (FALSE, not present) //专用密钥组件的用法标志(FALSE,不存在)
//–response-allowed允许的响应
00 //usage flag for the response-allowed component (FALSE, default value conveyed) 允许响应组件的用法标志(FALSE,默认值)
//–proposed-quality-of-service-建议的服务质量
00 //usage flag for the proposed-quality-of-service component (FALSE, not present) - 建议的服务质量组件的使用标志(FALSE,不存在)
//–proposed-quality-of-service
06 //the A-XDR encoding ofan Unsigned8 is its value
//–proposed-conformance
5f 1f //encoding the[APPLICATION 31] tag (ASN.1 explicit tag)
04 //encoding the length of the 'contents’field in octet (4)
00 //encoding of the number ofunused bits in the final octet of the BITSTRING
00 08 1d // encoding of the fixed lengthbitstring value.(LN/SN)
//–client-max-receive-pdu-size
00 00 //the A-XDRencoding of an Unsigned16 is its value.
*/
}
}
9a 7a
7e
}
//aare
R: 7E A053 03 00 22 00 23 30 40 A6 E6 E7 00 61 42 A1 09 06 07 60 85 74 05 08 01 01 A203 02 01 00 A3 05 A1 03 02 01
00 88 02 07 80 89 07 60 85 74 05 08 02 01 AA 0A 80 08 41 42 43 44 45 4647 48 BE 10 04 0E 08 00 06 5F 1F 04
00 00 08 1D 21 34 00 07 72 A4 7E
{
7E
A0 53
03
00 22 00 23
30
40 A6
E6 E7 00
61 //AARE tag
42 //AARE len
{
A1//COSEM_Application_Context_Name
09
06 //type = Objectidentifier
07 //length = 07
60 85 74 05 08 01 01
A2 //Tag of Association-result,
03 //Len of Association-result,
02 //type = structure
01 //length = 1
00 //
/*
Association-result ::= INTEGER
{
accepted (0),
rejected-permanent (1),
rejected-transient (2)
}
encoding the result component(tagged component [2])
A2 // encoding the tag &length for the result component ([2], Context-specific )
03 // encoding of the length of the tagged component¡¯s value field
-- encoding the result-component(INTEGER)
02 // encoding the choice for result(INTEGER, Universal)
01 // encoding of the length of theresult¡¯s value field (1 octets)
00 // encoding of the value of theResult (0, accepted)
*/
A3 //Tag ofAssociate-source-diagnostic,
05 //Len ofAssociate-source-diagnostic
A1
03
0201 00
/*
Associate-source-diagnostic ::=CHOICE
{
acse-service-user [1] INTEGER
{
null (0),
no-reason-given (1),
application-context-name-not-supported(2),
authentication-mechanism-name-not-recognised(11),
authentication-mechanism-name-required(12),
authentication-failure(13),
authentication-required(14)
},
acse-service-provider [2] INTEGER
{
null (0),
no-reason-given (1),
no-common-acse-version(2)
}
}
-- encoding theresult-source-diagnostic (tagged component [3])
A3 //encoding the tag for the result-source-diagnostic component ([3],Context-specific )
05 //encoding of the length of the tagged component¡¯s value field
A1 //encoding the tag for the acse-service-user CHOICE (1)
03 //encoding of the length of the tagged component’s value field
–encoding the result-source-diagnostics component (INTEGER)
02 //encoding the choice for result-source-diagnostics (INTEGER, Universal)
01 //encoding of the length of the value field (1 octets)
00 //encoding of the value: 0, no diagnostics provided.
*/
//Contents below can be ignored.
88 //IMPLICIT ACSE-requirementsOPTIONAL
02
07
80
89 //IMPLICIT mechanism-nameOPTIONAL
07
60 85 74 05 08 02 01
AA //EXPLICIT authentication-valueOPTIONAL
0A
80
08
41 42 43 44 45 46 47 48
//User information must be exist.
/*
xDLMS-Initiate.response :: =SEQUENCE
{
negotiated-quality-of-service [0] IMPLICITInteger8 OPTIONAL,
negotiated-dlms-version-number Unsigned8,
negotiated-conformance Conformance,
server-max-receive-pdu-size Unsigned16,
vaa-name ObjectName
}
*/
BE //User information (x-DLMScontext)
10
{
04 // encoding the choicefor user-information (OCTET STRING, Universal)
0E // encoding of thelength of the OCTET STRING¡¯s value field (14 octets)
//-- A-XDR encoding thexDLMS-Initiate.response PDU
08 //encoding the tag (explicit tag) of theDLMS PDU CHOICE (InitiateResponse)
//-- encoding the negotiated-quality-of-servicecomponent (OPTIONAL, not present)
00 // usage flag for theproposed-quality-of-service component (FALSE, not present)
//-- encoding of thenegotiated-dlms-version-number component (Unsigned8, value=6)
06 //negotiated-dlms-version-number
//-- encoding the conformance block[APPLICATION 31] IMPLICIT BITSTRING (SIZE(24))
5F 1F // encoding the [APPLICATION 31] tag(ASN.1 explicit tag)
04 // encoding the length of the'contents' field in octet (4)
00 // encoding of the number of unused bitsin the final octet of the bitstring
// encodingof the fixed length BITSTRING value
00 08 1D
//-- encoding theserver-max-receive-pdu-size component (Unsigned16, value=0x01F4)
21 34 // the A-XDR encoding of an Unsigned16is its value
//-- encoding the VAA-Name component(Unsigned16, value=0x0007 for LN and FA 00 for SN)
00 07 // the A-XDR encoding of an Unsigned16is its value . 00 07 == LN
}
}
72 A4
7E
(四)必要的数据请求帧,和响应帧
在应用层连接建立之后,client就可以向server请求数据了 这里只介绍两个基本的数据通讯帧
所有的DLMS应用数据帧都是COSEMpdu的一部分下面首先列出COSEMpdu
COSEMpdu ::= CHOICE {
– standardized DLMS PDUs used in COSEM
– DLMS PDUs (no encryption selected30)
initiateRequest [1] IMPLICIT InitiateRequest,
readRequest [5] IMPLICIT ReadRequest,
writeRequest [6] IMPLICIT WriteRequest,
initiateResponse [8] IMPLICIT InitiateResponse,
readResponse [12] IMPLICIT ReadResponse,
writeResponse [13] IMPLICIT WriteResponse,
confirmedServiceError [14] ConfirmedServiceError,
unconfirmedWriteRequest [22] IMPLICIT UnconfirmedWriteRequest,
informationReportRequest [24] IMPLICIT InformationReportRequest,
– the two ACSE APDUs
aarq AARQ-apdu
aare AARE-apdu,
– APDUs used for data communication servicesusing LN referencing
用于使用LN引用的数据通信服务的apdu
get-request [192] IMPLICIT GET-Request,
set-request [193] IMPLICIT SET-Request,
event-notification-request [194] IMPLICIT EVENT-NOTIFICATION-Request,
action-request [195] IMPLICIT ACTION-Request,
get-response [196] IMPLICIT GET-Response,
set-response [197] IMPLICIT SET-Response,
action-response [199] IMPLICIT ACTION-Response,
– global ciphered pdus
glo-get-request [200] IMPLICITOCTET STRING,
glo-set-request [201] IMPLICITOCTET STRING,
glo-event-notification-request [202] IMPLICIT OCTET STRING,
glo-action-request [203] IMPLICITOCTET STRING,
glo-get-response [204] IMPLICITOCTET STRING,
glo-set-response [205] IMPLICITOCTET STRING,
glo-action-response [207] IMPLICITOCTET STRING,
– dedicated ciphered pdus
ded-get-request [208] IMPLICITOCTET STRING,
ded-set-request [209] IMPLICITOCTET STRING,
ded-event-notification-request [210] IMPLICIT OCTET STRING,
ded-actionRequest [211] IMPLICITOCTET STRING,
ded-get-response [212] IMPLICITOCTET STRING,
ded-set-response [213] IMPLICITOCTET STRING,
ded-action-response [215] IMPLICITOCTET STRING
}
这里要说明一下OBIS:
在数据请求帧中,必须有Cosem-Attribute-Descriptor项:
Cosem-Attribute-Descriptor ::= SEQUENCE Cosem-属性描述符
{
class-id Cosem-Class-Id,
instance-id Cosem-Object-Instance-Id, OBIS
attribute-id Cosem-Object-Attribute-Id
}
其中的class-id attribute-id由本文参考文献【1】定义
Cosem-Object-Instance-Id由本文参考文献【5】定义
由参考文献【5】定义的内容即OBIS 它是由COSEM定义的一系列编码,共6个字节长 他的作用就是为每一种数据类型提供一个唯一的编码 有关OBIS的具体内容请参阅参考文献【5】
1) 数据请求帧GET-Request 跟698有点像了。
GET-Request ::= CHOICE
{
get-request-normal [1] IMPLICIT Get-Request-Normal,
get-request-next [2] IMPLICIT Get-Request-Next, 下一步获取请求,
get-request-with-list [3] IMPLICIT Get-Request-With-List隐式Get请求(带列表)
}
Get-Request-Normal ::= SEQUENCE
{
invoke-id-and-priority // Invoke-Id-And-Priority, 调用Id和优先级,
cosem-attribute-descriptor // Cosem-Attribute-Descriptor, Cosem属性描述符,
access-selection-parameters // Selective-Access-Descriptor OPTIONAL选择性访问描述符可选
}
Cosem-Attribute-Descriptor ::= SEQUENCE
{
class-id // Cosem-Class-Id, // 类id Cosem类id
instance-id // Cosem-Object-Instance-Id, // 实例id Cosem对象实例id
attribute-id //Cosem-Object-Attribute-Id //属性id Cosem对象属性id
}
Cosem-Object-Instance-Id ::= OCTET STRING(SIZE(6))
Cosem-Object-Attribute-Id ::= Integer8
上面的好像是请求连接的,跟698的相差很大,698的请求连接很简单的帧,这个帧太复杂了。可能是英语翻译不到位没有理解到。到时候需要在看看AARQ,AARE.
以请求反向有功为例:这里有点像是正常人看的了
S: 7e a0 1c 00 22 00 23 03 54 bd 5e e6 e6 00 c0 01 81 00 03 01 01 02 08 00 ff 02 00 9f 36 7e
解释:
7e a0 1c 00 22 00 23 03 54 bd 5e e6 e6 00 //Hdlchead 就相当于是固定搭配
c0 // get-request 他这个dlms的get-request是C0,698的是05 Cosemapdu[192],读取。
01 //Request Nomal 请求正常。 表示该读取的请求是合法的
81 // invoke-id(调用ID)(低7位:000 0001) and priority(最高位1),设置PIID 和 优先级,类似-PIID-ACD
00 // Get-Data-Result = data,获取数据结果。 这个应该是有个类似于698的那种流程的。
03 //Class id选择是那个类,698是在协议的那个APDU里面就包含了class_id
01 01 02 08 00 ff //反向总有功 OBIS
02 00 //反向总有功的第二属性,值域
9f 36 7e //HDLC Tail
2) 数据响应帧GET-Response
GET-Response ::= CHOICE
{
get-response-normal [1]IMPLICIT Get-Response-Normal,
get-response-with-datablock [2]IMPLICIT Get-Response-With-Datablock, 使用数据块获取响应,
get-response-with-list [3]IMPLICIT Get-Response-With-List使用列表获取响应
}
Get-Response-Normal ::= SEQUENCE
{
invoke-id-and-priority Invoke-Id-And-Priority,
result Get-Data-Result
}
Get-Data-Result ::= CHOICE
{
data [0] Data,//这个就是00 表示选择是数据,然后找一个类型,
data-access-result [1] IMPLICIT Data-Access-Result //这个在下面也有对应的解释
}
Data ::= CHOICE
{
null-data [0]IMPLICIT NULL,
array [1]IMPLICIT SEQUENCE OF Data,
structure [2]IMPLICIT SEQUENCE OF Data,
boolean [3]IMPLICIT BOOLEAN,
bit-string [4]IMPLICIT BIT STRING,
double-long [5]IMPLICIT Integer32,
double-long-unsigned [6]IMPLICIT Unsigned32,
floating-point [7]IMPLICIT OCTET STRING(SIZE(4))33,
octet-string [9]IMPLICIT OCTET STRING,
visible-string [10]IMPLICIT VisibleString,
time [11]IMPLICIT GeneralizedTime,
bcd [13]IMPLICIT Integer8,
integer [15]IMPLICIT Integer8,
long [16]IMPLICIT Integer16,
unsigned [17]IMPLICIT Unsigned8,
long-unsigned [18]IMPLICIT Unsigned16,
compact-array [19]IMPLICIT SEQUENCE
{
contents-description [0]TypeDescription,
array-contents [1]IMPLICIT OCTET STRING
}
long64 [20]IMPLICIT Integer64,
long64-unsigned [21]IMPLICIT Unsigned64,
enum [22]IMPLICIT ENUMERATED,
float32 [23]IMPLICIT OCTET STRING (SIZE(4)),
float64 [24]IMPLICIT OCTET STRING (SIZE(8)),
don’t-care [255]IMPLICIT NULL
}
Data-Access-Result ::= ENUMERATED 列举 这个就好像那个什么错误码。
{
success (0), //成功,
hardware-fault (1), //硬件失败
temporary-failure (2), //,,失败,
read-write-denied (3),
object-undefined (4),
object-class-inconsistent (9),
object-unavailable (11),
type-unmatched (12),
scope-of-access-violated (13),
data-block-unavailable (14),
long-get-aborted (15),
no-long-get-in-progress (16),
long-set-aborted (17),
no-long-set-in-progress (18),
other-reason (250)
}
以响应“请求反向有功”为例:
R: 7E A0 18 03 00 22 00 23 74 E4 13 E6 E7 00C4 01 81 00 06 00 35 7B 18 CD E8 7E
解释:
7E A0 18 03 00 22 00 23 74 E4 13 E6 E7 00 //Hdlc head E6 E7 00这个在LLC(逻辑链路控制层)发这个表示是服务器发送的帧,如果是E6 E6 00表示是客户机发送的。
C4 01 //Response Normal, C4是get-response, 01表示normal,就叫响应成功
81 // invoke-id(000 0001) and priority(1) 调用的ID和权限,
类似698的PIID-ACD
00 //by data Get-Data-Result ::= CHOICE在这个里面选择的是data这个
06 //数据长度, 这个恐怕不是数据长度吧,应该是数据类型。06表示一个32位的整数,4*8=32刚好也对应下面的4个字节的数据。
00 35 7B 18 //反向有功值
CD E8 7E//HDLC Tail fcs和7e结束。
五、对于接收到的数据帧的拆解
接收到的请求数据都是按照AXDR编码的 ,接收到的数据帧的数据结构,在参考文献【7】中都有详细解释
以下给出数据帧解析的实例:
五、例:Load_profile 加载配置文件
这个配置文件即是链路层和应用层的连接。
//hdlclink
//SNRM 这个是建立链路层的一个连接,需要连接的时候就用的这个。故而不用LLC控制码,因为不是数据通信。只有当数据通信的时候才需要这样搞。
S: 7e a0 21 00 22 00 23 03 93 0b 14 81 80 12 05 01 80 06 01 80 07 04 00 00 00 01 08 04 00 00 00 07 65 5e 7e
//UA
R: 7E A021 03 00 22 00 23 73 28 F0 81 80 12 05 01 80 06 01 80 07 04 00 00 00 01 08 0400 00 00 01 53 3B 7E
应用层连接的建立是通过client端发送AARQ数据帧,server端响应AARE数据帧来实现的 这两个数据帧主要是配置应用层数据通讯的参数
看上文,AARQ实例。
//aarq 这个是应用层的连接建立
S: 7e a047 00 22 00 23 03 10 d0 5e e6 e6 00 60 36 a1 09 06 07 60 85 74 05 08 01 01 8a02 07 80 8b 07 60 85 74 05 08 02 01 ac 0a 80 08 41 42 43 44 45 46 47 48 be 1004 0e 01 00 00 00 06 5f 1f 04 00 00 08 1d 00 00 9a 7a 7e
//aare
R: 7E A053 03 00 22 00 23 30 40 A6 E6 E7 00 61 42 A1 09 06 07 60 85 74 05 08 01 01 A203 02 01 00 A3 05 A1 03 02 01 00 88 02 07 80 89 07 60 85 74 05 08 02 01 AA 0A80 08 41 42 43 44 45 46 47 48 BE 10 04 0E 08 00 06 5F 1F 04 00 00 08 1D 21 3400 07 72 A4 7E
//
S: 7e a00a 00 22 00 23 03 31 12 87 7e
这个31表示准备接收下一个数据帧。
R: 7E A00A 03 00 22 00 23 31 3F 84 7E
S: 7e a00a 00 22 00 23 03 31 12 87 7e
R: 7E A00A 03 00 22 00 23 31 3F 84 7E
//request data c0=get-request
S: 7e a01c 00 22 00 23 03 32 8d 58 e6 e6 00 c0 01 81
00 07 0000 63 80 01 ff 02 00
44 58 7e // 这里的32就是普通的信息传输帧。
R: 7E A04F 03 00 22 00 23 52 07 E2 E6 E7 00 C4 01 81 00
01 01 //1 array,长度也是1
02 06 //6 strures 里面有2个结构体,其实也可以看出这里面如果涉及到很多的数据,就需要用数组来区分,同一(类)(不是同一类型)的可以放在一个结构体,比如人的五官,可以是一个结构体,人的四肢可以是一个结构体。
这个就相当于是一个结构体数组。
Int array[2];
Arrry[0] = &struct1;, 这样也相当于数组里面放了结构体,只是这个是数组是让这个结构体方便查找。
Arrry[1] = &struct2; 个人理解供参考。
09 06 01 01 01 1B 00 FF //1
02 02 0F 03 16 1B //2
09 06 01 01 02 1B 00 FF //3
02 02 0F 03 16 1B //4
09 0C 07 D3 05 08 FF FF FF FF FF FF FF FF //5
09 0C 07 D3 05 17 FF FF FF FF FF FF FF FF //6
F6 CE 7E
S: 7e a00a 00 22 00 23 03 51 14 e4 7e
R: 7E A00A 03 00 22 00 23 51 39 E7 7E
S: 7e a01c 00 22 00 23 03 54 bd 5e e6 e6 00 c0 01 81 00 07
ff ff 62 85 02 ff
02 00
7a 23 7e
R: 7E A88C 03 00 22 00 23 74 FA 62 E6 E7 00 C4 01 81 00
01 //arry
01 //total 1 array
02 //structure
34 //total 52 structure
02 03 //3 structure
09 06 01 01 15 08 00 FF //octetstring , 6 bytes long ,obiscode(01 01 15 08 00 FF)
06 0000 00 00 //Unsigned32(0x06),data (00 00 00 00)
02 02 //scal and unit.02 typ=strcture, 02 num = 2 strctures.
0F 00 // scal :Êý¾ÝÀàÐÍInteger8(0x0f),Êý¾ÝÄÚÈÝdata (0x00) //¼û62056µÄpdf
16 1E // unit :ENUMERATED(0x16) , data(0x1e =wh)
//unit:enum.Thiscan be founded in Blue book 3rd edition.
//attention (By DL): according to XDR ,whena datatype(Such as octet string,array ,stucture)
//can’t express the data length ,a datalength byte should exist.On the other hand ,when the length can be expressed by
//the data type(such asInteger8,Unsigned32,and ENUMERATED),the length byte arnn’t exist.
//¸ù¾ÝBER±àÂë??
02 03
09 06 01 01 29 08 00 FF 06 00 00 00 00 02 02 0F 00 16 1E
02 03
09 06 01 01 3D 08 00 FF 06 00 00 00 00 02 02 0F 00 16 1E
02 03
09 06 01 01 01 08 00 FF 06 00 00 00 00 02 02 0F 00 16 1E
02 03
09 06 01 01 16 08 00 FF 06 00 2E 6E FE 02 02 0F 00 16 1E
02 03
09 06 01 01 2A 08 00 FF 06 00
9E 5D 7E
S: 7e a00a 00 22 00 23 03 71 16 c5 7e
R: 7E A88C 03 00 22 00 23 76 E8 41
00 00 00 02 02 0F 00 16 1E 02 03
09 06 0101 3E 08 00 FF 06 00 00 00 00 02 02 0F 00 16 1E 0203
09 06 0101 02 08 00 FF 06 00 2E 6E FE 02 02 0F 00 16 1E 0203
09 06 0101 17 08 00 FF 06 00 00 00 00 02 02 0F 00 16 20 0203
09 06 0101 2B 08 00 FF 06 00 00 00 82 02 02 0F 00 16 20 0203
09 06 0101 3F 08 00 FF 06 00 00 00 00 02 02 0F 00 16 20 0203
09 06 0101 03 08 00 FF 06 00 00 00
CB 00 7E
S: 7e a00a 00 22 00 23 03 91 18 22 7e
R: 7E A88C 03 00 22 00 23 78 96 A8
82 02 02 0F00 16 20 02 03
09 06 0101 18 08 00 FF 06 00 03 C2 EE 02 02 0F 00 16 20 0203
09 06 0101 2C 08 00 FF 06 00 00 00 82 02 02 0F 00 16 20 0203
09 06 0101 40 08 00 FF 06 00 00 00 00 02 02 0F 00 16 20 0203
09 06 0101 04 08 00 FF 06 00 03 C3 70 02 02 0F 00 16 20 0203
09 06 0101 19 08 00 FF 06 00 00 00 00 02 02 0F 00 16 20 0203
09 06 0101 2D 08 00 FF 06 00 00 00 50 02
88 CB7E
S: 7e a00a 00 22 00 23 03 b1 1a 03 7e
R: 7E A88C 03 00 22 00 23 7A 84 8B
02 0F00 16 20 02 03
09 06 0101 41 08 00 FF 06 00 00 00 00 02 02 0F 00 16 20 0203
09 06 0101 05 08 00 FF 06 00 00 00 50 02 02 0F 00 16 20 0203
09 06 0101 1A 08 00 FF 06 00 00 00 00 02 02 0F 00 16 20 0203
09 06 0101 2E 08 00 FF 06 00 00 00 32 02 02 0F 00 16 20 0203
09 06 0101 42 08 00 FF 06 00 00 00 00 02 02 0F 00 16 20 0203
09 06 0101 06 08 00 FF 06 00 00 00 32 02 02 0F
B9 E0 7E
S: 7e a00a 00 22 00 23 03 d1 1c 60 7e
R: 7E A88C 03 00 22 00 23 7C B2 EE
00 16 20 0203
09 06 0101 1B 08 00 FF 06 00 03 C2 EE 02 02 0F 00 16 20 0203
09 06 0101 2F 08 00 FF 06 00 00 00 64 02 02 0F 00 16 20 0203
09 06 0101 43 08 00 FF 06 00 00 00 00 02 02 0F 00 16 20 0203
09 06 0101 07 08 00 FF 06 00 03 C3 52 02 02 0F 00 16 20 0203
09 06 0101 1C 08 00 FF 06 00 00 00 00 02 02 0F 00 16 20 0203
09 06 0101 30 08 00 FF 06 00 00 00 1E 02 02 0F 00 16
A8 C8 7E
S: 7e a00a 00 22 00 23 03 f1 1e 41 7e
R: 7E A88C 03 00 22 00 23 7E A0 CD
20 0203
09 06 0101 44 08 00 FF 06 00 00 00 00 02 02 0F 00 16 20 0203
09 06 0101 08 08 00 FF 06 00 00 00 1E 02 02 0F 00 16 20 0203
09 06 0101 1D 08 00 FF 06 00 00 00 00 02 02 0F 00 16 1F 0203
09 06 0101 31 08 00 FF 06 00 00 02 62 02 02 0F 00 16 1F 0203
09 06 0101 45 08 00 FF 06 00 00 00 00 02 02 0F 00 16 1F 0203
09 06 0101 09 08 00 FF 06 00 00 02 62 02 02 0F 00 16 1F 02
5B 0C 7E
S: 7e a00a 00 22 00 23 03 11 10 a6 7e
R: 7E A88C 03 00 22 00 23 70 DE 24
03
09 06 01 01 1E 08 00 FF 06 00 2E 8D B2 02 020F 00 16 1F 02 03
09 06 01 01 32 08 00 FF 06 00 00 00 00 02 020F 00 16 1F 02 03
09 06 01 01 46 08 00 FF 06 00 00 00 00 02 020F 00 16 1F 02 03
09 06 01 01 0A 08 00 FF 06 00 2E 8D B2 02 020F 00 16 1F 02 03
09 06 FF 02 FF 08 00 FF 06 00 00 00 00 02 020F 00 16 FF 02 03
09 06 FF 03 FF 08 00 FF 06 00 00 00 00 02 020F 00 16 FF 02 03
09
1C EB 7E
S: 7e a00a 00 22 00 23 03 31 12 87 7e
R: 7E A88C 03 00 22 00 23 72 CC 07
06 FF 04 FF 08 00 FF 06 00 00 00 00 02 02 0F 00 16 FF 02 03
09 06 FF 05 FF 08 00 FF 06 00 00 00 00 02 020F 00 16 FF 02 03
09 06 FF 02 FF 08 00 FF 06 00 00 00 00 02 020F 00 16 FF 02 03
09 06 FF 03 FF 08 00 FF 06 00 00 00 00 02 020F 00 16 FF 02 03
09 06 FF 04 FF 08 00 FF 06 00 00 00 00 02 020F 00 16 FF 02 03
09 06 FF 05 FF 08 00 FF 06 00 00 00 00 02 020F 00 16 FF 02 03
09 06 FF
29 95 7E
S: 7e a00a 00 22 00 23 03 51 14 e4 7e
R: 7E A05B 03 00 22 00 23 74 8C 7C 06 FF 08 00
FF 06 00 00 00 00 02 020F 00 16 FF 02 03
09 06 FF 07 FF 08 00 FF 06 00 00 00 00 02 020F 00 16 FF 02 03
09 06 FF 08 FF 08 00 FF 06 00 00 00 00 02 020F 00 16 FF 02 03
09 06 FF 09 FF 08 00 FF 06 00 00 00 00 02 020F 00 16 FF
0B 2E 7E
S: 7e a00a 00 22 00 23 03 71 16 c5 7e
R: 7E A00A 03 00 22 00 23 71 3B C6 7E
S: 7e a00a 00 22 00 23 03 71 16 c5 7e
R: 7E A00A 03 00 22 00 23 71 3B C6 7E
S: 7e a00a 00 22 00 23 03 71 16 c5 7e
R: 7E A00A 03 00 22 00 23 71 3B C6 7E
S: 7e a00a 00 22 00 23 03 71 16 c5 7e
R: 7E A00A 03 00 22 00 23 71 3B C6 7E
S: 7e a00a 00 22 00 23 03 71 16 c5 7e
R: 7E A00A 03 00 22 00 23 71 3B C6 7E
S: 7e a00a 00 22 00 23 03 71 16 c5 7e
R: 7E A00A 03 00 22 00 23 71 3B C6 7E
//disclink
S: 7e a00a 00 22 00 23 03 53 06 c7 7e
R: 7E A00A 03 00 22 00 23 1F 43 4C 7E
六、请求数据实例
这里给出几个数据通讯的实例,供程序员编程时参考
1、 请求电量
请求正向有功总电量,及分费率电量 ,这个就是完整的请求数据实例
S代表发送,R代表接收,不要看成,S是服务器了。
S:7E A0 0A 00 22 0023 03 93 0A 01 7E //建立链路层连接SNRM
R:7E A0 21 03 00 2200 23 73 28 F0 81 80 12 05 01 80 06 01 80 07 04 00 00 00 01 08 04 00 00 00 0153 3B 7E //UI响应。
S:7E A0 46 00 22 0023 03 10 05 C1 E6 E6 00 60 35 A1 09 06 07 60 85 74 05 08 01 01 8A 02 07 80 8B07 60 85 74 05 08 02 01 AC 0A 80 08 41 42 43 44 45 46 47 48 BE 10 04 0E 01 0000 00 06 5F 04 00 00 00 14 00 00 BD BF 7E
//这个好像是建立应用层连接里面有个标志AARQ,AARE 60 85 74 05 08 01 01
//从下面开始就要算RRR 和 SSS了,都是信息I帧了。,先从这里算的RRR+1,上的10的时候SSS未动。
R:7E A0 52 03 00 2200 23 30 95 39 E6 E7 00 61 41 A1 09 06 07 60 85 74 05 08 01 01 A2 03 02 01 00A3 05 A1 03 02 01 00 88 02 07 80 89 07 60 85 74 05 08 02 01 AA 0A 80 08 41 4243 44 45 46 47 48 BE 0F 04 0D 08 00 06 5F 04 00 00 00 14 21 34 00 07 14 53 7E //同上这个就是AARE, 应用层建立连接,
S:7E A0 1B 00 22 0023 03 32 95 9F E6 E6 00 C0 01 81 00 03 01 01 01 08 00 FF 02 0C F6 7E //上建立好了就可以来发送请求正向有功总电量
R:7E A0 18 03 00 2200 23 52 D0 57 E6 E7 00 C4 01 81 00 06 00 06 1B 98 5A 60 7E //这个是回应 81是那个PIID-ACD,优先级和序号, 可以看46页也就是,导航栏上的反向有功的例子。00 06 1B 98这就是那个有功电量= 40.0280 KW/H应该是这样的。
S:7E A0 1B 00 22 0023 03 54 A5 99 E6 E6 00 C0 01 81 00 04 01 01 01 08 01 FF 02 DE 30 7E //这个是请求费率
R:7E A0 18 03 00 2200 23 74 E4 13 E6 E7 00 C4 01 81 00 06 00 01 C7 14 A0 54 7E //响应费率 这个06就是32位的整数类型,所以后面是4个字节代表是数据。费率=116500单位不知道是啥。
//这里的76 = 0111 0110对应I帧,把P/F位和最后一个0去掉,那么即是RRR=3 , SSS=3, 按照以前说的第一次发送请求不算。那么刚好加起来是RRR , SSS都是3次。
S:7E A0 1B 00 22 0023 03 76 B5 9B E6 E6 00 C0 01 81 00 04 01 01 01 08 02 FF 02 BA DF 7E
//后面的需要对照那个类似698的OAD才知道是啥意思。
R:7E A0 18 03 00 2200 23 96 F8 D7 E6 E7 00 C4 01 81 00 06 00 03 17 5E 7D 53 7E //这里的96=1001 0110, 就是RRR=4 SSS=3
S:7E A0 1B 00 22 0023 03 98 C5 95 E6 E6 00 C0 01 81 00 04 01 01 01 08 03 FF 02 66 85 7E
R:7E A0 18 03 00 2200 23 B8 84 1F E6 E7 00 C4 01 81 00 06 00 01 3D 26 49 C7 7E
S:7E A0 1B 00 22 0023 03 BA D5 97 E6 E6 00 C0 01 81 00 04 01 01 01 08 04 FF 02 63 09 7E
R:7E A0 18 03 00 2200 23 DA 90 5F E6 E7 00 C4 01 81 00 06 00 00 00 00 7B DF 7E
S:7E A0 0A 00 22 0023 03 D1 1C 60 7E //RR帧准备接收帧。
R:7E A0 0A 03 00 2200 23 D1 31 63 7E
S:7E A0 0A 00 22 0023 03 53 06 C7 7E//这里53, 73就表示结束了。
R:7E A0 0A 03 00 2200 23 73 29 E5 7E
2、请求瞬时量(电压、电流、功率)
S:7E A0 0A 00 22 0023 03 93 0A 01 7E
R:7E A0 21 03 00 2200 23 73 28 F0 81 80 12 05 01 80 06 01 80 07 04 00 00 00 01 08 04 00 00 00 0153 3B 7E
S:7E A0 46 00 22 0023 03 10 05 C1 E6 E6 00 60 35 A1 09 06 07 60 85 74 05 08 01 01 8A 02 07 80 8B07 60 85 74 05 08 02 01 AC 0A 80 08 41 42 43 44 45 46 47 48 BE 10 04 0E 01 0000 00 06 5F 04 00 00 00 14 00 00 BD BF 7E
R:7E A0 52 03 00 2200 23 30 95 39 E6 E7 00 61 41 A1 09 06 07 60 85 74 05 08 01 01 A2 03 02 01 00A3 05 A1 03 02 01 00 88 02 07 80 89 07 60 85 74 05 08 02 01 AA 0A 80 08 41 4243 44 45 46 47 48 BE 0F 04 0D 08 00 06 5F 04 00 00 00 14 21 34 00 07 14 53 7E
//对于I帧其实规律也来了这个左边的数是奇数i+2, 右边的是偶数的i+2
S:7E A0 1B 00 22 0023 03 32 95 9F E6 E6 00 C0 01 81 00 03 01 01 1F 07 00 FF 02 0D 91 7E
R:7E A0 16 03 00 2200 23 52 F1 D1 E6 E7 00 C4 01 81 00 12 00 02 33 53 7E
S:7E A0 1B 00 22 0023 03 54 A5 99 E6 E6 00 C0 01 81 00 03 01 01 33 07 00 FF 02 AC 86 7E
R:7E A0 16 03 00 2200 23 74 C5 95 E6 E7 00 C4 01 81 00 12 00 02 33 53 7E
S:7E A0 1B 00 22 0023 03 76 B5 9B E6 E6 00 C0 01 81 00 03 01 01 47 07 00 FF 02 4F BE 7E
R:7E A0 16 03 00 2200 23 96 D9 51 E6 E7 00 C4 01 81 00 12 00 02 33 53 7E
S:7E A0 1B 00 22 0023 03 98 C5 95 E6 E6 00 C0 01 81 00 03 01 01 20 07 00 FF 02 20 2F 7E
R:7E A0 16 03 00 2200 23 B8 A5 99 E6 E7 00 C4 01 81 00 12 00 01 A8 61 7E
S:7E A0 1B 00 22 0023 03 BA D5 97 E6 E6 00 C0 01 81 00 03 01 01 34 07 00 FF 02 70 B6 7E
R:7E A0 16 03 00 2200 23 DA B1 D9 E6 E7 00 C4 01 81 00 12 00 01 A8 61 7E
S:7E A0 1B 00 22 0023 03 DC E5 91 E6 E6 00 C0 01 81 00 03 01 01 48 07 00 FF 02 B3 D4 7E
R:7E A0 16 03 00 2200 23 FC 85 9D E6 E7 00 C4 01 81 00 12 00 01 A8 61 7E
S:7E A0 0A 00 22 0023 03 F1 1E 41 7E
R:7E A0 0A 03 00 2200 23 F1 33 42 7E
S:7E A0 0A 00 22 0023 03 53 06 C7 7E // 断开
R:7E A0 0A 03 00 2200 23 73 29 E5 7E //同意断开
3、请求负荷曲线
S:7E A0 0A 00 22 0023 03 93 0A 01 7E
R:7E A0 21 03 00 2200 23 73 28 F0 81 80 12 05 01 80 06 01 80 07 04 00 00 00 01 08 04 00 00 00 0153 3B 7E
S:7E A0 46 00 22 0023 03 10 05 C1 E6 E6 00 60 35 A1 09 06 07 60 85 74 05 08 01 01 8A 02 07 80 8B07 60 85 74 05 08 02 01 AC 0A 80 08 41 42 43 44 45 46 47 48 BE 10 04 0E 01 0000 00 06 5F 04 00 00 00 14 00 00 BD BF 7E
R:7E A0 52 03 00 2200 23 30 95 39 E6 E7 00 61 41 A1 09 06 07 60 85 74 05 08 01 01 A2 03 02 01 00A3 05 A1 03 02 01 00 88 02 07 80 89 07 60 85 74 05 08 02 01 AA 0A 80 08 41 4243 44 45 46 47 48 BE 0F 04 0D 08 00 06 5F 04 00 00 00 14 21 34 00 07 14 53 7E
S:7E A0 3C 00 22 0023 03 32 0E 3B E6 E6 00 C0 01 81 00 07 00 00 63 01 00 FF 02 01 01 02 04 00 090C 07 D3 06 09 FF FF FF FF FF FF FF FF 09 0C 07 D3 06 0A FF FF FF FF FF FF FFFF DE 82 7E
R:7E A8 8C 03 00 2200 23 52 CE 26 E6 E7 00 C4 01 81 00 01 22 02 06 02 02 09 0C 07 D3 06 09 FF 091D 0D FF FF FF FF 04 06 40 00 00 00 10 00 00 10 00 00 02 06 00 00 00 00 10 0000 10 00 00 02 06 00 00 00 00 10 00 00 10 00 00 02 06 00 00 00 00 10 00 00 1000 00 02 06 00 00 00 00 10 00 00 10 00 00 02 06 00 00 00 00 10 00 00 10 00 0002 06 00 00 00 00 10 00 00 10 00 00 02 06 00 00 00 00 10 00 00 10 00 00 02 0600 00 00 83 9E 7E
S:7E A0 0A 00 22 0023 03 51 14 E4 7E
R:7E A8 8C 03 00 2200 23 54 F8 43 00 10 00 00 10 00 00 02 06 00 00 00 00 10 00 00 10 00 00 02 0600 00 00 00 10 00 00 10 00 00 02 06 00 00 00 00 10 00 00 10 00 00 02 06 00 0000 00 10 00 00 10 00 00 02 06 00 00 00 00 10 00 00 10 00 00 02 06 00 00 00 0010 00 00 10 00 00 02 06 00 00 00 00 10 00 00 10 00 00 02 06 00 00 00 00 10 0000 10 00 00 02 06 00 00 00 00 10 00 00 10 00 00 02 06 00 00 00 00 10 00 00 10 0000 02 F9 31 7E
S:7E A0 0A 00 22 0023 03 71 16 C5 7E
R:7E A8 8C 03 00 2200 23 56 EA 60 06 00 00 00 00 10 00 00 10 00 00 02 06 00 00 00 00 10 00 00 1000 00 02 06 00 00 00 00 10 00 00 10 00 00 02 06 00 00 00 00 10 00 00 10 00 0002 06 00 00 02 02 09 0C FF FF FF FF FF 0F 08 34 FF FF FF FF 04 06 40 02 02 090C FF FF FF FF FF 0F 0E 1F FF FF FF FF 04 06 40 10 00 00 10 00 00 02 06 00 0000 00 10 00 00 10 00 00 02 06 00 00 00 00 10 00 00 10 00 00 02 06 00 00 00 0010 00 00 14 24 7E
S:7E A0 0A 00 22 0023 03 91 18 22 7E
R:7E A0 75 03 00 2200 23 58 40 72 10 00 00 02 06 00 00 00 00 10 00 00 10 00 00 02 06 00 00 00 0010 00 00 10 00 00 02 06 00 00 00 00 10 00 00 10 00 00 02 06 00 00 00 00 10 0000 10 00 00 02 06 00 00 00 00 10 00 00 10 00 00 02 06 00 00 00 00 10 00 00 1000 00 02 06 00 02 02 09 0C FF FF FF FF FF 11 23 0C FF FF FF FF 04 06 40 00 0010 00 00 10 00 00 A2 1B 7E
S:7E A0 0A 00 22 0023 03 B1 1A 03 7E
R:7E A0 0A 03 00 2200 23 51 39 E7 7E
S:7E A0 0A 00 22 0023 03 53 06 C7 7E
R:7E A0 0A 03 00 2200 23 73 29 E5 7E
4、请求时间
S:7E A0 0A 00 22 0023 03 93 0A 01 7E
R:7E A0 21 03 00 2200 23 73 28 F0 81 80 12 05 01 80 06 01 80 07 04 00 00 00 01 08 04 00 00 00 0153 3B 7E
S:7E A0 46 00 22 0023 03 10 05 C1 E6 E6 00 60 35 A1 09 06 07 60 85 74 05 08 01 01 8A 02 07 80 8B07 60 85 74 05 08 02 01 AC 0A 80 08 41 42 43 44 45 46 47 48 BE 10 04 0E 01 0000 00 06 5F 04 00 00 00 14 00 00 BD BF 7E
R:7E A0 52 03 00 2200 23 30 95 39 E6 E7 00 61 41 A1 09 06 07 60 85 74 05 08 01 01 A2 03 02 01 00A3 05 A1 03 02 01 00 88 02 07 80 89 07 60 85 74 05 08 02 01 AA 0A 80 08 41 4243 44 45 46 47 48 BE 0F 04 0D 08 00 06 5F 04 00 00 00 14 21 34 00 07 14 53 7E
S:7E A0 1B 00 22 0023 03 32 95 9F E6 E6 00 C0 01 81 00 08 00 00 01 00 00 FF 02 46 2F 7E
R:7E A0 21 03 00 2200 23 52 A3 C0 E6 E7 00 C4 01 81 00 09 0C 07 D3 06 0E 06 0E 0D 03 FF FF FF 0010 38 7E
S:7E A0 0A 00 22 0023 03 51 14 E4 7E
R:7E A0 0A 03 00 2200 23 51 39 E7 7E
S:7E A0 0A 00 22 0023 03 53 06 C7 7E
R:7E A0 0A 03 00 2200 23 73 29 E5 7E
本文到这里就结束了 彻底理解DLMS协议是一个大的系统工程 这个协议的制定,又很多地方时面向通用性的 为实现通用性,其实协议中的很多地方不必那么复杂的地方,显得很复杂 同时这个协议又涉及到了许多别的标准,在看本文时最好同时参照本文的参考文献,将有助于理解本文
补充一:对于SNReferencing的解释 SN应用
When SN referencing is used, the attributes and methodsof each interface object are mapped to DLMS named variables. This isdone during the design of the meter.Each named variable is identified with a short name, which is a 16 bitunsigned integer.Attribute 1, the logical name of the object is mapped to aDLMS named variable identified by a base name. Except in the case of afew special objects, there are no general rules defined for assigning base names.All other attributes and methods of the object are then also mapped to DLMSnamed variables. The offsets between the base name and the short nameidentifying the other attributes and methods are defined in the definition ofeach interface class. The actual values of the short names thus depend on thenumber and kind of objects instantiated and the mapping strategy used. The basenames allocated in the metering equipment can be retrieved by reading theobject_list attribute of the SN Association object. When SN referencing is used,the DLMS named variables are accessed by the standard DLMS READ and WRITE services.
When LN referencing is used, attributesand methods are accessed via the logical name of the object, specifying theindex(es) of the attribute(s) and/or the method(s). Logical names are definedby OBIS. When LN referencing is used, the attributes and methods are accessedby the xDLMS GET/SET and ACTION services.
(Referencingfrom “DLMS User Association Frequently Asked Questions”)
使用SN引用时,每个接口对象的属性和方法都映射到DLMS命名变量。这是仪表设计期间的一个命令。每个命名变量用一个短名称标识,该名称是一个16位无符号整数。属性1,对象的逻辑名称映射到由基名称标识的aDLMS命名变量。除少数特殊对象外,没有定义用于分配基名称的一般规则。然后,该对象的所有其他属性和方法也映射到DLMSnamed变量。基名和识别其他属性和方法的短名之间的偏移量在每个接口类的定义中定义。因此,短名称的实际值取决于实例化对象的数量和类型以及所使用的映射策略。通过读取序列号关联对象的“对象列表”属性,可以检索在计量设备中分配的基名。使用SN引用时,标准DLMS读写服务将访问DLMS命名的变量。
使用LN引用时,通过对象的逻辑名称访问属性和方法,指定属性和/或方法的索引。逻辑名称由OBIS定义。使用LN引用时,属性和方法由xDLMS GET/SET和ACTION服务访问。
(参考“DLMS用户协会常见问题”)
SNReferencing 不同于LN Referencing 它使用一个整型数(WORD)即ShortName,来取代LN Referencing中的OBIS . Short Name 由厂家自定义.对于西门子D型表使用了SN . 因此只有在厂家提供SN的情况下,才可以使用SN的application-context-name 访问表内的数据.
下面是一个SN数据请求帧的例子:
S:7E A011 03 21 32 B7 3D E6 E6 00 05 01 02 FF 08 A0 E0 7E
7E A0 1103 21 32 B7 3D E6 E6 00
05//SN application-context-name ReadRequest
01 02 FF08 //short name and attribute 短名称和属性???
A0 E0 7E
补充二: 目前DLMS规约中用到的CLASS ID 和OBIS 表
数据名称 CLASS ID OBIS ATTRIBUTE属性
时钟 00 08 00 00 01 00 00 ff 02 00
正向有功(总) 00 03 01 01 01 08 00 ff 02 00
正向有功(费率一) 00 04 01 01 01 08 01 ff 02 00
正向有功(费率二) 00 04 01 01 01 08 02 ff 02 00
正向有功(费率三) 00 04 01 01 01 08 03 ff 02 00
正向有功(费率四) 00 04 01 01 01 08 04 ff 02 00
反向有功(总) 00 03 01 01 02 08 00 ff 02 00
反向有功(费率一) 00 04 01 01 02 08 01 ff 02 00
反向有功(费率二) 00 04 01 01 02 08 02 ff 02 00
反向有功(费率三) 00 04 01 01 02 08 03 ff 02 00
反向有功(费率四) 00 04 01 01 02 08 04 ff 02 00
有功功率(总) 00 03 01 01 01 07 00 ff 02 00
无功功率(总) 00 03 01 01 02 07 00 ff 02 00
L1电压 00 03 01 01 1f 07 00 ff 02 00
L2电压 00 03 01 01 33 07 00 ff 02 00
L3电压 00 03 01 01 47 07 00 ff 02 00
L1电流 00 03 01 01 20 07 00 ff 02 00
L2电流 00 03 01 01 34 07 00 ff 02 00
L3电流 00 03 01 01 48 07 00 ff 02 00