9 DLMS/COSEM application layer
9.1 DLMS/COSEM application layer main features
9.1.1 General
本子条款9.1概述了DLMS/COSEM AL提供的主要特性
9.1.2 DLMS/COSEM application layer structure
客户端和服务器DLMS/COSEM应用层的结构如图61所示。

DLMS/COSEM AL的主要组件是应用程序服务对象(ASO)。它向服务用户COSEM应用程序流程(AP)提供服务,并使用支持的层提供的服务。它在客户端和服务器端都包含三个必需的组件:
- Association Control Service 元素(ACSE);
- extended DLMS Application Service元素,xDLMS ASE;
- Control Function,CF。
在客户端,有第四个元素(可选),称为client SN_Mapper ASE
。
ACSE提供建立和发布应用关联的服务。见9.1.3
xDLMS ASE提供在COSEM AP之间传输数据的服务。见9.1.4。
Control Function (CF)元素指定ASO服务如何调用ACSE、xDLMS ASE和支持层服务的适当服务原语。见9.4.1。
客户端和服务器DLMS/COSEM ASO都可能包含其他可选的应用程序协议组件。
当服务器使用SN referencing时,可选的client SN_Mapper ASE
存在于客户端ASO中。它使用LN referencing和SN referencing提供服务之间的映射。见9.1.5。
DLMS/COSEM AL还执行OSI表示层的一些功能:
- 编码和解码ACSE apdu和xDLMS apdu,参见9.4.3;
- 或者,生成和使用表示ACSE和xDLMS apdu的XML文档;
- 应用压缩和解压;
- 应用,验证和删除加密保护。
9.1.3 The Association Control Service Element, ACSE
为了DLMS/COSEM面向连接(CO)通信配置文件的目的,使用ISO/IEC 15953:1999和ISO/IEC 15954:1999中规定的CO ACSE。
为association和释放提供的服务如下:
- COSEM-OPEN,见9.3.2;
- COSEM-RELEASE,见9.3.3;
- COSEM-ABORT,见9.3.4。
COSEM-OPEN
服务用于建立AAs。它基于ACSE A-ASSOCIATE服务。它让Application_Context_Name
、Security_Mechanism_Name
和xDLMS上下文参数
的值标识的ASE过程开始使用AA。AAs可以通过不同的方式建立:
- 已确认的AAs是通过消息交换(使用COSEM-OPEN服务)在客户端和服务器之间建立,以协商上下文。可以在单个客户端和单个服务器之间建立已确认的AAs;
- 未经确认的AAs是通过使用COSEM-OPEN服务从客户端发送到服务器的消息来建立的,使用服务器应该支持的上下文参数。可以在客户端和一个或多个服务器之间建立未经确认的AAs
只有客户端发送,服务端不回应。(多播,广播);
- 预先建立的AAs可能预先存在。在这种情况下,不使用COSEM-OPEN服务。客户机必须知道服务器支持的上下文。预先建立的AA可以是确认的,也可以是未确认的。
COSEM-RELEASE
服务用于释放AAs。如果成功,则完成对AA的使用,而不会丢失传输中的信息(优雅释放)。
在一些通信配置文件中(例如在基于TCP-UDP/IP的配置文件中)COSEM-RELEASE服务是基于ACSE A-RELEASE服务的。在其他一些通信配置文件中(例如在第3层,面向连接,HDLC基础协议中)在已确认的AA和支持协议层连接之间存在一对一的关系。在这样的配置文件中,只需断开相应的支持的层连接即可释放AA。不能释放预先建立的AA
并不依赖于 ACSE_RELEASE服务,在此种模型下的确认的应用连接简单关联到断开相应的底层连接
COSEM-ABORT
服务会导致AA异常释放,可能导致信息丢失。它不依赖于ACSE A-ABORT服务。
9.1.4 The xDLMS application service element
9.1.4.1 Overview
要访问COSEM对象的属性和方法,需要使用xDLMS ASE的服务。它是基于DLMS标准,IEC 61334-4-41:1996。本技术报告指定了一系列扩展,以在保持向后兼容性的同时扩展功能。扩展包括以下内容:
- 附加服务,见9.1.4.3;
- 附加机制,见9.1.4.4;
- 附加数据类型,见9.1.4.5;
- 新的DLMS版本号,见9.1.4.6;
- 新的一致性块,见9.1.4.7;
- 理清PDU大小的含义,参见9.1.4.8。
9.1.4.2 The xDLMS initiate service
为了建立xDLMS上下文,使用了IEC 61334-4-41:1996,5.2中指定的xDLMS Initiate服务。该服务集成在COSM-OPEN服务中,参见9.3.2。
9.1.4.3 COSEM object related xDLMS services
9.1.4.3.1 General
与COSEM对象相关的xDLMS服务用于访问COSEM对象属性和方法。DLMS UA 1000-1 Ed. 12.2:2017, 4.1.2规定了两种引用方法:
- Logical Name (LN) referencing;和
- Short Name (SN) referencing。
有关引用方法的更多信息,请参见9.1.4.4.2。
因此,指定了两个不同的xDLMS服务集:一个专门使用Logical Name (LN) referencing ,另一个专门使用short name (SN) referencing。可以认为存在两个不同的xDLMS ASEs:一个提供具有LN referencing的服务,另一个提供具有SN referencing的服务。客户端ASO总是使用带有LN referencing的xDLMS ASE
。服务器ASO可以使用带有LN referencing的xDLMS ASE,也可以使用带有SN referencing的xDLMS ASE,或者两者都使用
。
这些服务包括:
- 客户要求/征求的(
客户端请求
);或- 客户要求的服务还可以(见9.4.6.2):
- 已确认:在这种情况下,服务器对请求提供响应;
- 未确认:在这种情况下,服务器不提供对请求的响应。
- 客户要求的服务还可以(见9.4.6.2):
- 未请求的:这些总是由服务器发起,没有客户端先前的请求,
由服务器端发起,无需请求
。
不基于IEC 61334-4-41:1996中规定的DLMS服务的附加服务包括:
- 使用LN referencing访问COSEM对象属性和方法的GET、SET、ACTION和ACCESS;
- DataNotification服务用于服务器向客户端推送数据;
- EventNotification服务用于通知客户端发生在服务器上的事件。
9.1.4.3.2 xDLMS services used by the client with LN referencing
在LN referencing
的情况下,COSEM对象属性和方法通过它们所属的COSEM对象实例的标识符被引用。对于这个引用方法,指定了以下附加服务:
- GET服务被客户端用来请求服务器返回一个或多个属性的值,见9.3.6;
- SET服务被客户端用来请求服务器替换一个或多个属性的内容,见9.3.7;
- ACTION服务被客户端用来请求服务器调用一个或多个方法。调用方法可能意味着发送方法调用参数并接收返回参数,见9.3.8;
- ACCESS服务,一个统一的服务,客户端可以使用一个.request访问多个属性和/或方法;见9.3.9。
客户端可以以已确认或未确认
的方式调用这些服务。
9.1.4.3.3 xDLMS services used by the client with SN referencing
在SN referencing
的情况下,COSEM对象属性和方法被映射到IEC 61334-4-41: 1996,10.1.2中指定的DLMS命名变量。
使用SN referencing
的xDLMS服务基于IEC 61334-4- 41:20 96子条款10.4 - 10.6中规定的DLMS变量访问服务,它们如下:
- Read 服务被客户端用来请求服务器返回一个或多个属性的值,或者在期望返回参数时调用一个或多个方法。这是一个确认服务。见9.3.14;
- Write服务被客户端用来请求服务器替换一个或多个属性的内容,或者在没有返回参数的情况下调用一个或多个方法。这是一个确认服务。见9.3.15;
- UnconfirmedWrite服务被客户端用来请求服务器替换一个或多个属性的内容,或者在没有返回参数时调用一个或多个方法。这是一个未确认服务。见9.3.16。
9.1.4.3.4 Unsolicited services
未经请求的服务由服务器根据预定义的条件(例如时间表、触发器或事件)启动,以向客户端通知一个或多个属性的值,就好像它们是由客户端请求的一样。
要支持推送操作,可以使用DataNotification服务,请参见9.3.10。它可以在使用SN referencing或者LN referencing的应用程序上下文中使用。
DataNotification服务与"Push setup"COSEM对象一起使用,请参见DLMS UA 1000-1 Ed.12.2:2017,4.4.8。
为了支持事件通知,提供了以下未经请求的服务:
- 对于LN referencing,EventNotification服务,见9.3.11;
- 对于SN referencing,InformationReport服务,见9.3.17。此服务基于IEC 61334-4-41:1996 10.7。
9.1.4.3.5 Selective access
在某些COSEM接口类的情况下,可以选择性地访问属性,这意味着可以根据需要访问整个属性或其选定部分。为此,访问选择器和参数被指定为相关属性规范的一部分。
为了使用这种可能性,可以使用访问选择参数来调用与属性相关的服务。
在LN referencing的情况下,此功能称为选择性访问;参见9.3.6和9.3.7。这是一个可协商的特性;见9.4.6.1。
在SN referencing的情况下,此功能称为参数化访问;见9.3.14、9.3.15和9.3.16。这是一个可协商的特性;见9.4.6.1。
9.1.4.3.6 Multiple references
在与COSEM对象相关的服务调用中,可以引用一个或多个已命名的变量、属性和/或方法。使用多个引用是一个可协商的特性。见9.4.6.1。
9.1.4.3.7 Attribute_0 referencing
由于GET、SET和ACCESS服务是一种特殊功能,因此可以使用Attribute_0引用。按照惯例,COSEM对象的属性编号为1~n,其中Attribute_1为COSEM对象的逻辑名称。Attribute_0有一个特殊的含义:它引用所有索引为正的属性(公共属性)。在9.3.6中解释了在GET服务中使用Attribute_0引用,在9.3.7中解释了SET服务,在9.3.9中解释了ACCESS服务。
如DLMS UA 1000-1 Ed. 12.2: 2017,4.1.2所述,制造商可以使用负数为任何对象添加专有方法和/或属性。
9.1.4.4 Additional mechanisms
9.1.4.4.1 Overview
与IEC 61334-4-41:1996中指定的DLMS相比,xDLMS指定了几个新机制来改进功能、灵活性和效率。其他机制有:
- 使用逻辑名logical names进行引用;
- 服务调用的标识;
- 优先处理;
- 传输长应用程序消息;
- 可组合的xDLMS消息;
- 压缩和解压;
- 通用加密保护;
- 通用块传输(GBT)。
9.1.4.4.2 Referencing methods and service mapping
要使用xDLMS服务访问COSEM对象属性和方法,必须引用它们。正如已经在9.1.4.3.1中提到的,DLMS UA 1000-1 Ed. 12.2:2017,4.1.2指定了两个引用方法:
- Logical Name (LN) referencing;和
- Short Name (SN) referencing.
在LN referencing的情况下,COSEM对象属性和方法通过它们所属的COSEM对象实例的逻辑名称(COSEM_Object_Instance_ID)被引用。在SN referencing的情况下,COSEM对象属性和方法被映射到DLMS命名变量。
因此,指定了两个xDLMS ASEs:一个使用带LN referencing的xDLMS服务,另一个使用带SN referencing的xDLMS服务。
在客户端,为了透明地为AP处理不同的引用方法,AL使用带有LN referencing的xDLMS ASE。在COSEM客户端AP和通信协议之间使用独特的标准化服务集——使用不同的引用方法隐藏DLMS/COSEM服务器的特殊性——允许指定应用程序编程接口(API)。这是一个显式指定的接口,对应于在给定计算环境(例如Windows、UNIX等)中运行的应用程序的服务集。使用这个公共API规范,可以在不了解给定服务器特殊性的情况下开发客户机应用程序。
在服务器端,可以使用带有LN referencing的xDLMS ASE,也可以使用带有SN referencing的xDLMS ASE,或者同时使用两个xDLMS ASE。
对于已确认的AA,在AA建立阶段通过COSEM应用程序上下文协商引用方法。在AA建立的生命周期内不得改变。在给定的AA中使用LN或SN服务是独占的。 在未经确认和预先建立的AA的情况下,客户端AL应该知道服务器支持的引用方法。 当服务器使用LN referencing时,两端的服务是相同的。当服务器使用SN referencing时,客户端的SN_Mapper ASE将SN referencing映射为LN referencing,反之亦然。参见9.1.2和9.1.5。
9.1.4.4.3 Identification of service invocations: the Invoke_Id parameter
在客户机/服务器模型中,请求由客户机发送,响应由服务器发送。允许客户端在收到对前一个请求的响应之前发送多个请求,前提是底层允许这样做。
因此,为了能够识别哪个响应对应于每个请求,有必要在请求中包含引用。
Invoke_Id
参数用于此目的。该参数的值由客户端分配,以便每个请求都携带不同的Invoke_Id。服务器将把Invoke_Id
复制到相应的响应中。
需要用Invoke_Id
来标识数据包,这样客户端才能判断响应是对应哪个请求的
在ACCESS和DataNotification服务中(参见9.3.9和9.3.10),使用Long-Invoke-Id参数代替Invoke_Id参数。
EventNotification服务不包含
Invoke_Id参数
。此功能仅在LN referencing时可用
。
9.1.4.4.4 Priority handling
对于使用LN referencing的数据传输服务,有两个优先级级别:正常(FALSE)和高(TRUE)。此特性允许在完成对前一个请求的响应之前接收对新请求的响应。
通常,服务器按照接收顺序(FIFS, First in, First served)为传入的服务请求提供服务。但是,将优先级参数设置为高(TRUE)的请求在优先级设置为普通(FALSE)的前一个请求之前提供服务。响应具有与相应请求相同的优先级标志。管理优先级是一个可协商的特性;看到9.4.6.1。
注1:由于服务调用使用Invoke_Id标识,因此具有相同优先级的服务可以以任意顺序提供。
注2:如果不支持该特性,高优先级的请求将以NORMAL优先级服务。
对于使用SN referencing的服务,此功能不可用。服务器以FIFS为基础处理服务。
9.1.4.4.5 Transferring long messages
xDLMS服务原语由xDLMS apdu以编码形式携带。此编码形式可能比协商的客户端/服务器最大接收PDU大小长。要传输这种长消息,有两种机制可用:
a) 9.1.4.4.9规定的general block transfer(GBT)机制;
B) service-specific block transfer机制。该机制可用于GET、SET、ACTION、Read和Write服务。在这种情况下,服务原语调用只包含数据(例如属性值)的一部分——一个块,因此编码的形式适合于单个APDU.
service-specific block transfer没有块恢复机制
--------------------SLF NOTE Start--------------------
- service-specific block transfer在以下情况下不可用:
unconfirmed services
unsolicited services
(DataNotification, EventNotification and InformationReport)- ACCESS service
- service-specific block transfer只能一包一包顺序传,不支持流式传输,不支持恢复丢失块。加密是加密一个block,而不是整个APDU,服务专用数字签名不可用。相反,GBT机制可以与任何 xDLMS APDU 一起使用,包括通用密码和通用签名APDU。它提供双向块传输、流和丢失块恢复。当需要加密保护时,对完整的APDU进行加密保护,然后被保护的APDU以块的形式传输,如图87所示。
--------------------SLF NOTE End--------------------
使用general block transfer或service-specific block transfer的是一个可协商的特性,参见9.4.6.1。
适合协商的Client / Server最大接收PDU大小的APDU可能太长,无法容纳支持层的单个帧/包。如果支持的层提供分段,则可以传输此类apdu;见第10条。
9.1.4.4.6 Composable xDLMS messages
处理xDLMS消息的三个重要方面是编码/解码
,应用、验证/删除加密保护
和块传输
。
可组合xDLMS消息的概念将这三个方面分开,如图62所示。另请参见图88。

一旦AL构建了与AP调用的服务原语相对应的APDU,就可以使用general protection机制来应用加密保护。当一个未受保护或受保护的APDU太长而无法容纳协商的APDU大小时,可以应用general block transfer机制。
这些机制可以应用于所有xDLMS apdu。
注1:对于GET、SET、ACTION、EventNotification、Read and Write、UnconfirmedWrite和InformationReport服务,可以使用特定的服务保护和apdu来提供service-specific加密保护。
注2:对于GET、SET、ACTION、Read、Write和UnconfirmedWrite和服务,可以使用特定的服务请求/响应类型和apdu进行service-specific的块传输。
9.1.4.4.7 Compression and decompression
为了优化通信媒体的使用,可以压缩要发送的xDLMS apdu并解压接收的xDLMS apdu。具体操作请参见9.2.3.6。
9.1.4.4.8 General protection
该机制可用于对任何xDLMS APDU应用加密保护,这允许在客户机和服务器之间或第三方和服务器之间应用多层保护。参见9.2.2.5
为此,可以使用以下APDUs;见9.2.7.2.3:
- general-ded-ciphering和general-glo-ciphering APDUs;
- general-ciphering APDUs;
- general-signing APDU。
使用general protection机制是一个可协商的特性,参见9.4.6.1。
9.1.4.4.9 General block transfer (GBT)
该机制可用于以块形式传输任何xDLMS APDU。使用GBT,块由general-block-transfer而不是service-specific "with-datablock" APDUs携带。
注1:ACCESS和DataNotification服务不提供service-specific块传输机制。
- GBT机制支持双向块传输、流和丢失块恢复:
- 双向区块传输意味着,当一方发送区块时,另一方不仅确认收到的区块,而且如果它有区块要发送,它也可以在接收区块的同时发送它们;
注2:当需要双向传输较长的业务参数时,可使用双向块传输。
- 流意味着可以由一方发送多个区块,而无需另一方对每个区块进行确认;
- 丢失的块恢复意味着如果接收到的块没有被确认,它可以再次发送。如果使用流,丢失的块恢复发生在流窗口的末尾。
- 双向区块传输意味着,当一方发送区块时,另一方不仅确认收到的区块,而且如果它有区块要发送,它也可以在接收区块的同时发送它们;
GBT机制由AL使用9.3.5中指定的块传输流参数进行管理。
使用general block transfer机制是一个可协商的特性,参见9.4.6.1。
general block transfer机制的协议在9.4.6.13中规定。
9.1.4.5 Additional data types
附加信息在9.5和9.6中指定。
9.1.4.6 xDLMS version number
新的DLMS版本号(对应于xDLMS ASE的第一个版本)是6。
9.1.4.7 xDLMS conformance block
xDLMS conformance block支持具有扩展功能的优化DLMS/COSEM服务器实现。它可以通过标签"Application 31"与DLMS conformance block区分开来。参见9.4.6.1、9.5和9.6。
xDLMS conformance block是xDLMS上下文的一部分。
对于已确认的AA,在AA建立阶段通过xDLMS上下文协商conformance block。在AA建立的生命周期内不得改变。
在未经确认和预先建立的AA的情况下,客户端AL应该知道服务器支持的conformance block。
9.1.4.8 Maximum PDU size
为了明确客户端和服务器可使用的最大PDU大小的含义,对PDU进行了表12所示的修改。xDLMS Initiate服务使用这些名称作为PDU大小。
过去 | 新的 |
---|---|
IEC 61334-4-41:1996, 5.2.2, Table 3 | |
建议最大PDU大小 | Client最大接收PDU大小 |
协商最大PDU大小 | Server最大接收PDU大小 |
IEC 61334-4-41:1996, 5.2.3, 7th | |
提议的Max PDU Size参数类型为Unsigned16,提议交换的DLMS APDUs的最大长度(以字节表示)。初始化请求中提出的值必须足够大,以便始终允许Initiate Error PDU的传输 | Client Max Receive PDU Size参数类型为Unsigned16,包含服务器可以发送的DLMS APDUs的最大长度(以字节表示)。客户端将丢弃任何超过此最大长度的pdu。该值必须足够大,以便始终允许AARE APDU传输。 12以下的值为保留值。取值为0表示不限制PDU的大小。 |
IEC 61334-4-41:1996, 5.2.3, last paragraph | |
协商的最大PDU大小参数类型为Unsigned16,包含交换的DLMS APDUs的最大长度(以字节表示)。超过此长度的PDU将被丢弃。此最大长度计算为建议最大PDU大小的最小值和VDE-handler可能支持的最大PDU大小。 | Server Max Receive PDU Size参数类型为Unsigned16,包含客户端可以发送的DLMS APDUs的最大长度(以字节表示)。服务器将丢弃任何超过此最大长度的pdu。 12以下的值为保留值。取值为0表示不限制PDU的大小。 |
9.1.5 Layer management services
层管理服务仅具有局部重要性。因此,这些服务的规范不在本技术报告的范围之内。
特定的SetMapperTable服务在9.3.18中定义。
9.1.6 Summary of DLMS/COSEM application layer services
图63中显示了DLMS/COSEM AL顶部可用服务的摘要。层管理服务没有显示。尽管服务原语在客户端和服务器端是不同的,但APDUs是相同的。
Note 1 例如,当客户端AP调用GET.request服务原语,客户端AL构建GET-Request APDU。当服务器AL接收到此消息时,它调用GET.ind服务原语。
DLMS/COSEM AL服务在9.3中指定。DLMS/COSEM AL协议在9.4中指定。在9.5中指定了ACSE和xDLMS apdu的抽象语法。XML模式在9.6中定义。
编码示例在条款11、12、13和14中提供。

注2:客户端AP始终使用LN referencing。如果服务器使用SN referencing,则映射由Client SN_Mapper ASE执行。因此,服务原语ZZ.ind和ZZ.res可能是LN或SN服务原语。LN/SN服务映射在9.5中有规定。
注3:不能通过SN referencing的方式将ACCESS业务映射给其他业务
9.1.7 DLMS/COSEM application layer protocols
DLMS/COSEM AL协议指定了使用面向连接的ACSE过程进行AA控制和authentication的信息传输过程,以及使用xDLMS过程在COSEM客户端和服务器之间进行数据传输的过程。因此,DLMS/COSEM AL协议基于ISO/IEC 15954:1999中指定的ACSE标准和IEC 61334-4-41:1996中指定的DLMS标准,并扩展了DLMS/COSEM。这些程序的定义如下:
- 通过使用支持协议层的服务,对等ACSE和xDLMS协议机制之间的交互;
- ACSE和xDLMS协议机制与其服务用户之间的交互。
DLMS/COSEM AL协议在9.4中指定。
9.2 Information security in DLMS/COSEM
9.2.1 Overview
本章子条款9.2描述并规定:
- DLMS/COSEM安全概念,见9.2.2;
- 选择的加密算法,见9.2.3;
- 安全密钥,参见9.2.4、9.2.5和9.2.6;
- 使用加密算法进行实体认证,xDLMS APDU保护和COSEM数据保护,参见9.2.7。
9.2.2 The DLMS/COSEM security concept
DLMS/COSEM服务器的资源(COSEM对象属性和方法)可以由应用程序关联中的DLMS/COSEM客户端访问,见4.5。
在建立AA期间,客户机和服务器必须标识自己。服务器还可能要求客户端的用户去标识自己。此外,服务器可能要求客户端对自己进行认证,而客户端也可能要求服务器对自己进行认证。识别和认证机制在9.2.2.2中规定。
一旦建立了AA,就可以根据安全上下文和访问权限使用xDLMS服务访问COSEM对象属性和方法。参见9.2.2.3和9.2.2.4。
可以对携带服务原语的xDLMS apdu进行加密保护。所需的保护由安全上下文和访问权限决定。为了支持第三方和服务器之间的端到端的安全性,这些第三方还可以使用客户机作为代理访问服务器的资源。消息保护的概念将在9.2.2.5中进一步解释。
此外,xDLMS apdu携带的COSEM数据可以进行加密保护;见9.2.2.6.
由于这些安全机制应用于应用程序进程/应用层
级别,因此可以在所有DLMS/COSEM通信配置文件中使用它们。
Note:较低的层可能提供额外的安全性
9.2.2.2 Identification and authentication
9.2.2.2.1 Identification
如4.3.3所述,DLMS/COSEM AE与支持AL的协议层中的服务接入点(Service Access point, SAP)绑定。这些SAP存在于AA内携带xDLMS APDUs的PDUs中。
客户端用户识别机制
使服务器能够区分客户端上的不同用户(可能是操作员或第三方),以记录他们访问电表的活动。见4.3.6。
9.2.2.2.2 Authentication mechanisms
9.2.2.2.2.1 Overview
认证机制决定了通信实体在建立AA时使用的认证协议。

注1:COSEM-OPEN服务原语由AARQ/AARE apdu携带。COSEM-RELEASE服务原语由RLRQ/RLRE apdu携带(当使用时)。参见9.3.2和9.3.3。
注2:(System_Title)、(Certificate)、(Client_User_Id)为可选参数。
注3:在预先建立的AA中,不进行认证。
注4:COSEM-RELEASE服务可以通过在RLRQ中包含一个加密的xDLMS Initiate.request/.response APDU来加密保护。
有三种不同的身份验证机制可用于不同的身份验证安全级别:
- 无安全(最低级别安全)认证;看到9.2.2.2.2.2;
- Low Level Security (LLS)认证,见9.2.2.2.2.3;
注1:在ITU-T X.811:1995中,这被称为单边认证,0类机制。
- HLS (High Level Security)认证,请参见9.2.2.2.2.4。
注2:在ITU-T X.811:1995中,这被称为使用质询机制的相互认证。
如图64所示。认证机制采用名称标识,请参见9.4.2.2.3
在AA建立阶段(阶段1),消息交换(阶段2)的安全性与client-server身份验证无关。即使在不进行client-server认证的情况下,也可以使用加密保护的apdu来保证消息的安全性
9.2.2.2.2.2 No security (Lowest Level Security) authentication
无安全(最低级别安全)认证的目的是允许客户端从服务器检索一些基本信息。这种身份验证机制不需要任何身份验证;客户端可以访问安全上下文中的COSEM对象属性和方法以及给定AA中流行的访问权限。
9.2.2.2.2.3 Low Level Security (LLS) authentication
在这种情况下,服务器要求客户机通过提供服务器知道的密码来对自己进行认证。密码由当前的"Association SN/ LN"对象持有,该对象对要建立的AA进行建模。"Association SN/LN"对象提供了更改密钥的方法。
如果接受提供的密码,则可以建立AA,否则将被拒绝。
COSEM-OPEN服务支持LLS身份验证(见9.3.2)如下:
- 客户端发送一个"secret"到服务器,使用COSEM-OPEN.request服务原语;
- 服务器检查"secret"是否正确;
- 如果正确的话,验证通过,可以建立AA。从这一刻起,协商内容是有效的;
- 如果不正确的话,AA将被拒绝;
- 建立AA的结果和诊断信息使用COSEM-OPEN.response服务原语发送回服务器
9.2.2.2.2.4 High Level Security (HLS) authentication
在这种情况下,客户机和服务器都必须成功地对自己进行认证才能建立AA。HLS认证是一个四步的过程,由COSEM-OPEN服务和"Association SN/LN"接口类的reply_to_HLS_authentication方法支持:
- Pass 1:客户端发送一个"challenge"
CtoS
和附加信息
(取决于认证机制)到服务器; - Pass 2:服务器发送一个"challenge"
StoC
和附加信息
(取决于认证机制)到客户端;
如果StoC与CtoS相同,客户应拒绝,并中止AA建立过程。所以 StoC 与 CtoS 必须是独立生成的且不同的 - Pass 3:客户端根据对给定AA有效的HLS认证机制的规则处理StoC和附加信息,并将结果发送给服务器。服务器检查f(StoC)是否是正确处理的结果,如果是,则接受客户端的认证;
- Pass 4:服务器根据对给定AA有效的HLS认证机制的规则处理CtoS和附加信息,并将结果发送给客户端。客户端检查f(CtoS)是否是正确处理的结果,如果是,则接受服务器的认证。
COSEM-OPEN服务支持Pass 1和Pass 2。
在通过Pass 2之后,假设提议的应用程序上下文和xDLMS上下文是可接受的,服务器使用协商的应用程序上下文
授予对当前"Association SN/LN"对象的reply_to_HLS_authentication方法
的访问权。
"Association SN/LN"对象reply_to_HLS_authentication的方法
支持Pass 3和Pass 4。如果成功执行了Pass 3和Pass 4,则使用协商好的应用程序上下文和xDLMS上下文建立AA。
--------------------SLF NOTE Start--------------------
- 总结,由服务端先校验客户端合法性,再由客户端校验服务端合法性。
- 应用程序上下文和xDLMS上下文Pass2之后已经存在了,但激活要等到Pass4完成
- Pass3和Pass4 依赖于
reply_to_HLS_authentication
--------------------SLF NOTE End--------------------
如果传输了专用密钥,则可以从此时开始使用。
否则,客户端或服务器将终止。
有几种可用的HLS身份验证机制。这些在9.2.7.4中有进一步的说明。
在某些HLS身份验证机制中,challenge
的处理涉及使用HLS密钥。
"Association SN/LN"接口类提供了一个更改HLS "secret"的方法:change_HLS_secret。
在客户端发出change_HLS_secret() -或change_LLS_secret() -方法后,它期望从服务器得到一个
确认密钥已更改
的响应。有可能是服务器发送了确认,但由于通信问题,客户端没有收到确认。因此,客户端不知道秘密是否被更改。为简单起见,服务器不提供对这种情况的任何特殊支持;也就是说,这是留给客户来处理这种情况。
9.2.2.3 Security context
安全上下文定义了与加密转换相关的安全属性,并包括以下元素:
- 安全套件,确定可用的安全算法,见9.2.3.7;
- 安全策略,确定一般应用于AA内交换的所有xDLMS apdu的保护类型。可能的安全策略在9.2.7.2.2中指定;
- 与给定安全算法相关的安全材料,包括安全密钥、初始化向量、公钥证书等。由于每个安全算法的安全资料都是特定的,所以在相关条款中详细说明了这些要素。
9.2.2.4 Access rights
对属性的访问权限可以是:no_access、read_only、write_only或read_and_write。
对方法的访问权限可以是no_access或access。
此外,访问权限可以规定将加密保护应用于携带用于访问特定COSEM对象属性/方法的服务原语的xDLMS APDUs。.request和.response所需的保护可以独立配置。
可以对访问特定的属性或方法的APDUs单独配置加密,.request 和.response也可以
访问权限由相关的"Association SN/LN"对象持有;参见DLMS UA 1000-1 Ed.12.2:2017, 4.4.3和4.4.4。可能的访问权限在9.2.7.2.2中指定。
所应用的保护应满足安全策略和访问权限规定的要求中较强的一方。
9.2.2.5 Application layer message security
DLMS/COSEM通过提供加密保护xDLMS apdu的方法来确保AL安全性。这种保护可以是认证、加密和数字签名的任何组合,并且可以由多方以多层方式应用。该保护由发起者应用,并由接收者验证和删除。
收到的请求或响应,只有在对承载请求或响应的信息的保护能够成功验证和移除的情况下,才应进行处理。
特定于项目的配套规范可以指定用于接受和处理消息的附加标准。
客户机和服务器之间的消息保护概念如图65所示

- 方法1
- Client=>Server
general protected APDU封装了一个携带
COSEM对象相关服务请求
的APDU - Server=>Client
general protected APDU封装了一个携带
COSEM对象相关服务响应
的APDU - Server=>Client
general protected APDU封装了一个携带
一个COSEM对象相关的未请求的服务请求(DataNotification)
的APDU
- 方法2
- Client=>Server
service specific protected APDU携带
COSEM对象相关的服务请求
- Server=>Client
service specific protected APDU携带
COSEM对象相关的服务响应
为了确保端到端的消息安全性,第三方必须能够与DLMS/COSEM服务器交换受保护的xDLMS服务请求。在这种情况下,客户端充当代理,这意味着第三方是第三方想要到达的客户端和服务器之间的某个AAs的用户。
第三方和服务器之间的消息保护概念如图66所示。

第三方:
- DLMS/COSEM可以生成和处理封装带有COSEM对象相关服务请求和响应的xDLMS apdu的消息;
- 它能够对携带请求的xDLMS APDU应用自己的保护;
- 它能够验证
应用于服务器和/或客户端的响应
的保护。
DLMS/COSEM客户端:
- 作为第三方和服务器之间的中间人;
- 根据第三方客户端消息中包含的信息,为第三方提供适当的AA;
- 验证第三方是否有权使用该AA;
验证方法不在本技术报告的范围之内
- 可以验证第三方申请的保护;
- 将第三方客户端消息封装到general protected的xDLMS APDU中;
- 它可以验证服务器对封装COSEM对象相关服务响应或未经请求的服务请求的APDU应用的保护;(Push操作时);
- 它可以对发送到第三方的受保护xDLMS apdu应用自己的保护。
服务器
- 应(预先)与第三方使用的客户端建立AA;
- 它可以检查使用AA的第三方的身份;
- 一旦成功验证客户和/或第三方应用的保护,应提供对安全策略和访问权限所确定的COSEM对象属性和方法的访问;
- 它应该准备响应(或者,在推送操作的情况下,一个未经请求的服务请求)并应用由传入请求的保护、访问权限和安全策略决定的保护。
加密保护在xDLMS apdu上的应用在9.2.7.2中有详细说明。
9.2.2.6 COSEM data security
COSEM数据,即COSEM对象属性、方法调用参数和返回参数的值也可以加密保护。当需要时,通过"Data protection"对象间接访问相关属性和方法,这些对象对COSEM数据应用和验证/删除保护;参见DLMS UA 1000-1 Ed.12:2017,4.4.9。
见9.2.7.5
9.2.3 Cryptographic algorithms
9.2.3.1 Overview
DLMS/COSEM采用密码来保护信息。
以下内容摘自NIST SP 800-21:2005, 3.1。
密码学是数学的一个分支,它以数据转换为基础,可用于提供多种安全服务:机密性、数据完整性、认证、授权和不可否认性。密码学依赖于两个基本组件:算法(或密码学方法)和密钥。该算法是一个数学函数,密钥是在转换中使用的一个参数。
加密算法和密钥用于对数据应用加密保护(例如,加密数据或生成数字签名)以及删除或检查保护(例如,解密加密数据或验证数字签名)。
认可的加密算法有三种基本类型:
- 不需要密钥的加密哈希函数(尽管它们可以在使用密钥的模式下使用)。哈希函数通常用作算法的组件,以提供安全服务。见99.2.3.2;
- 对称密钥算法(通常称为密钥算法),它使用单个密钥(由发送方和接收方共享)来应用保护并删除或检查保护。对称密钥算法相对容易实现,并提供高吞吐量。见9.2.3.3;
- 非对称密钥算法(通常称为公钥算法),它使用两个密钥(即密钥对):一个公钥和一个私钥,它们在数学上彼此相关。与对称密钥算法相比,非对称密钥算法的实现非常复杂,需要更多的计算量。见9.2.3.4。
为了使用加密技术,加密密钥必须"到位",即必须为使用加密技术的各方建立密钥。见9.2.4。
9.2.3.2 Hash function
以下文本引用自NIST SP 800-21:2005, 3.2。
哈希函数生成较长消息的简短表示。一个好的哈希函数是一个单向函数:它很容易从一个特定的输入计算哈希值;然而,将这个过程从哈希值恢复回输入是非常困难的。对于一个好的哈希函数,找到产生相同哈希值的两个特定输入也是极其困难的。由于这些特性,哈希函数通常用于确定数据是否已更改。
哈希函数接受任意长度的输入并输出固定长度
的值。哈希函数输出的常用名称包括哈希值
和消息摘要
。图67描述了哈希函数的使用。
哈希值(H1)是根据数据(M1)计算的。然后M1和H1被保存或传输。稍后,通过将接收到的数据标记为M2(而不是M1)并在接收到的值上计算新的哈希值(H2)来检查检索或接收到的数据的正确性。如果新计算的哈希值(H2)等于检索或接收的哈希值(H1),则可以假设检索或接收的数据(M2)与原始数据(M1)相同(即M1 = M2)。
哈希算法在DLMS/COSEM中用于以下目的:
- 数字签名,见9.2.3.4.4;
- 密钥协商,见9.2.3.4.6;和
- HLS认证。具体使用的算法取决于认证机制,请参见9.2.7.4。
数字签名和密钥协商采用安全套件规定的算法,参见表19。
9.2.3.3 Symmetric key algorithms
9.2.3.3.1 General
对称密钥算法在DLMS/COSEM中用于以下目的:
- 使用HLS认证机制对通信伙伴进行认证,见9.2.7.4;
- xDLMS消息的认证和加密,见9.2.7.2;
- COSEM数据的认证和加密,参见9.2.7.5。
注:以下内容摘自NIST SP 800-21:2005, 3.3。
对称密钥算法(通常称为秘密密钥算法)使用单个密钥来应用保护和删除或检查保护。例如,用于加密数据的密钥也用于解密加密的数据。如果数据要保留其加密保护,则必须对该密钥保密。对称密钥算法用于通过加密提供机密性,或通过验证保证真实性或完整性,或者在密钥建立期间使用。
用于一种用途的钥匙不得用于其他用途。(参见NIST SP 800-57:2012)
9.2.3.3.2 Encryption and decryption
注:以下文本摘自NIST SP 800-21:2005, 3.3.1。
加密用于为数据提供机密性。要保护的数据称为明文。加密将数据转换成密文。使用解密可以将密文转换回明文。
只有使用与加密数据相同的密钥才能从密文中恢复明文数据。知道加密算法但没有正确密钥的未经授权的密文接收者不应该能够解密密文。然而,任何拥有密钥和加密算法的人都可以很容易地解密密文并获得原始的明文数据。
图68描述了加密和解密过程。加密过程使用明文(P)和密钥(K)生成密文(C)。解密过程使用密文(C)和相同的密钥(K)来恢复明文(P)。

使用对称密钥块密码算法,相同的明文块和密钥将始终产生相同的密文块。此属性不能提供可接受的安全性。因此,已经定义了加密操作模式来解决这个问题(参见9.2.3.3.4)。
9.2.3.3.3 Advanced Encryption Standard
对于DLMS/COSEM,应使用FIPS PUB 197:2001中规定的高级加密标准(AES)。AES在加密或解密操作期间对数据块进行操作。由于这个原因,AES被称为分组密码算法。
以下内容摘自NIST SP 800-21:2005, 3.3.1.3。
AES使用128 bit、192 bit或256 bit密钥对128 bit块中的数据进行加密和解密。所有三个密钥大小都足够了。
AES提供了安全性、性能、效率、易于实现和灵活性的组合。具体来说,该算法在各种计算环境中的硬件和软件上都表现良好。此外,该算法对内存的要求非常低,因此非常适合空间有限的环境。
9.2.3.3.4 Encryption Modes of Operation
以下内容引用自NIST SP 800- 21:21 2005, 3.3.1.4。
使用对称密钥块密码算法,当使用相同的对称密钥时,相同的明文块将始终加密为相同的密文块。如果一个典型消息(数据流)中的多个块是单独加密的,攻击者可以很容易地替换单个块,可能不会被发现。此外,明文中的某些类型的数据模式,例如重复的块,在密文中是明显的。
通过将基本加密算法与可变初始化值(通常称为初始化向量)和来自加密操作的信息的反馈规则相结合,已经定义了加密操作模式来解决这个问题。
NIST SP 800-38D:2007指定了Galois/Counter Mode,一种与关联数据进行验证加密的算法,以及它的专门化GMAC,用于在未加密的数据上生成消息认证码(MAC)。GCM和GMAC是底层经过批准的对称密钥分组密码的操作模式。见9.2.3.3.3。
--------------------SLF NOTE Start--------------------
AES-GCM 可规避相同明文块加密成相同密文块带来的重复特性检测,密文块批量篡改的问题。
--------------------SLF NOTE End--------------------
9.2.3.3.5 Message Authentication Code
以下文本摘自NIST SP 800-21:2005, 3.3.2。
消息认证码(MAC)提供了真实性和完整性的保证。MAC是数据上的加密校验和,用于保证数据没有更改或被更改,并且MAC是由预期的一方(发送方)计算的。
通常,MAC用于共享密钥的双方之间,以验证双方之间交换的信息。
图69描述了消息验证码(MAC)的使用
MAC(MAC1)是通过密钥(K)对数据(M1)进行计算,然后保存或传输M1和MAC1。稍后,通过将检索或接收到的数据标记为M2并使用相同的密钥(K)计算MAC (MAC2)来检查检索或接收到的数据的真实性。如果检索或接收到的MAC (MAC1)与新计算的MAC (MAC2)相同,则可以假设检索或接收到的数据(M2)与原始数据(M1)相同(即M1 = M2)。验证方也知道发送方是谁,因为没有其他人知道密钥。
通常,MAC用于检测从初始生成MAC到验证接收到的MAC之间发生的数据修改。它们不检测MAC最初生成之前发生的错误。
消息完整性通常使用称为错误检测码的非加密技术来提供。然而,这些代码可以被攻击者修改,从而使攻击者受益。使用经过批准的加密机制(如MAC)可以解决这个问题。也就是说,MAC提供的完整性是基于不知道加密密钥就不可能生成MAC的假设。不知道密钥的攻击者将无法修改数据,然后在修改的数据上生成真实的MAC。因此,MAC密钥保密是至关重要的。
--------------------SLF NOTE Start--------------------
MAC 全称是 Message Authentication Code,中文名称为消息认证码,一串由密钥和密文生成的固定值,有时也称 Auth Tag。
- MAC 的使用流程如下:
- 首先
Sender
和Receiver
共享同一个Key
,约定一个MAC计算算法Algorithm
Sender
把要传递的消息Message
通过Key
和Algorithm
计算出MAC
,将Message
和MAC
发送给Receiver
Receiver
收到Message
和MAC
后,将Message
通过约定的Key
和算法Algorithm
计算出MAC_1
,通过对比MAC
和MAC_1
是否相等MAC
==MAC_1
消息无篡改且是Sender
发布的MAC
!=MAC_1
消息有篡改或者根本不是Sender
发布的,也就是有问题
- 首先

消息认证码是密码学家工具箱中的6大工具之一:对称密码、公钥密码、单向散列函数、消息认证码、数字签名和伪随机数生成器。
MAC 作用与 HASH 函数相似,但比哈希要复杂,都可以验证完整性,不同的是MAC需要密钥
而HASH不需要密钥
。MAC还能验证真实性,即使内容被篡改因为没有密钥也无法生成MAC
--------------------SLF NOTE End--------------------
9.2.3.3.6 Key wrapping
对称密钥算法可用于使用密钥封装密钥(也称为密钥加密密钥)封装(即加密)密钥材料。包裹的钥匙可以被安全地存储或传输。打开钥匙材料需要使用与原始封装过程中使用的相同的钥匙封装。
密钥封装与简单加密的不同之处在于,封装过程包含完整性特性。在密钥展开过程中,此完整性功能检测对包裹的密钥的有意或者无意修改。为了DLMS/COSEM的目的,应使用AES密钥封装算法;见9.2.3.3.8。
9.2.3.3.7 Galois/Counter Mode
9.2.3.3.7.1 General
以下文本摘自NIST SP 800-38D:2007,条款3。
Galois/Counter Mode(GCM)是一种使用关联数据进行验证加密的算法。GCM是由一个块大小为128 bit(16字节)
的对称密钥块密码构建的,例如高级加密标准(AES)算法,参见FIPS PUB 197。因此,GCM是AES算法的一种操作模式。
GCM使用Counter操作模式的一种变体来保证数据的机密性。
GCM使用在二进制Galois(即有限)字段(GHASH)上定义的通用哈希函数来保证机密数据的真实性(每次调用最多64 GB)。GCM还可以为未加密的其他数据(每次调用的长度实际上是无限的)提供验证保证。
如果GCM输入被限制为不需要加密的数据,那么GCM的专门化结果(称为GMAC)只是输入数据上的一种验证模式。
GCM提供比(非加密)校验和或错误检测代码更强的验证保护;特别是,GCM可以检测意外的数据修改
和故意的、未经授权的修改
。
在DLMS/COSEM中,也可以使用GCM仅提供机密性:在这种情况下,不计算和检查验证标记
。
--------------------SLF NOTE Start--------------------
GMAC 全称是 Galois Message Authentication Code,中文名称为伽罗瓦消息验证码。
GMAC 就是利用伽罗华域(Galois Field,GF,有限域)乘法运算来计算消息的 MAC 值。
GCM 是 AES 算法的一种运行模式。加密或认证可选,可以仅加密或仅认证
GCM 全称为 Galois/Counter Mode,可以看出 G 是指 GMAC,C 是指 CTR。它在 CTR 加密的基础上增加 GMAC 的特性,解决了 CTR 不能对加密消息进行完整性校验的问题。
GCM既可以实现校验,也可以实现加解密功能
GCM 加密所需数据:明文 P、加密密钥 Key、初始向量 IV、附加消息 F。
- GCM 加密步骤如下:
- 将 P 分为 P1、P2、…、Pn,Px 长度 <= 128bit
- 生成累加计数器 C0、C1、C2、…、Cn,由密钥 Key 计算出密钥 H
- 将 IV、C0 进行运算(连接、加和、异或等)得到 IV_C0,用 Key 加密 IV_C0 得到 IVC0
- 将 IV、C1 进行运算(连接、加和、异或等)得到 IV_C1,用 Key 加密 IV_C1 得到 IVC1,将 IVC1、P1 做异或运算得到 C1,用密钥 H 通过 GMAC 算法将附加消息 F 计算出 F1, F1 与 C1 做异或运算得到 FC1
- 将 IV、C2 进行运算(连接、加和、异或等)得到 IV_C2,用 Key 加密 IV_C2 得到 IVC2,将 IVC2、P2 做异或运算得到 C2,用密钥 H 通过 GMAC 算法将附加消息 FC1 计算出 F2, F2 与 C2 做异或运算得到 FC2
- ...
- 将 IV、Cn 进行运算(连接、加和、异或等)得到 IV_Cn,用 Key 加密 IV_Cn 得到 IVCn,将 IVCn、Pn 做异或运算得到 Cn,用密钥 H 通过 GMAC 算法将附加消息 FC(n-1) 计算出 Fn, Fn 与 Cn 做异或运算得到 FCn
- 拼接 C1、…Cn 得到密文 C,用密钥 H 通过 GMAC 算法结合 FCn 和 IVC0 最终计算出 MAC

--------------------SLF NOTE End--------------------
9.2.3.3.7.2 GCM functions
以下操作以NIST SP 800-38D: 2007,5.2为标准。
构成GCM的两个功能被称为认证加密和认证解密;参见图70。
经过认证的加密功能对机密数据进行加密,并在机密数据和任何其他非机密数据上计算认证标记。经过认证的解密功能根据标签的验证对机密数据进行解密。
当输入限制为非机密数据时,生成的GCM变体称为GMAC。对于GMAC,经过认证的加解密功能变成了在非机密数据上生成和验证认证标签的功能
。
最后,如果不需要认证,则经过认证的加密函数会加密机密数据,但不会计算认证标记。经过认证的解密功能解密机密数据,但不计算和验证认证标记。
在DLMS/COSEM中,认证和加密的使用由9.2.7.2.4中规定的安全控制字节的第4位和第5位表示。
-
a)经过认证的加密功能(事先给了分组密码密钥EK)有三个输入字符串:
- 明文,记为P;
- 附加认证数据(AAD),记为A;
- 初始化向量(IV),记为IV。
明文和AAD是GCM保护的两类数据。
GCM保护明文和AAD的真实性;GCM还保护明文的机密性
,而AAD则是透明的
。
IV本质上是一个nonce,即在指定(安全)上下文中唯一的值,它决定对要保护的输入数据调用经过认证的加密功能。见9.2.3.3.7.3。
经过认证的加密功能输入字符串的位长应满足以下要求:- len(P)<239-256;
- len(A)<264-1;
- 1≤len(IV)≤264-1。
P、A和IV的位长都是8的倍数,因此这些值都是字节串。
有两个输出:
与明文P的比特长度相同的密文
,记为C;- 一个认证标记,或简称标记,表示为T。
-
b)经过认证的解密函数(事先给了分组密码密钥EK)有四个输入字符串:
- 初始化向量,记为IV;
- 密文,记为C;
- 附加认证数据(AAD),表示为A;
- 认证标记,记为T。
输出如下所示:
- 对应于密文C的明文P,或者
- 本技术报告中称为FAIL的特殊错误代码。
输出P表示T是IV、A、C的正确认证标签;否则,输出为FAIL。
9.2.3.3.7.3 The initialization vector, IV
在DLMS/COSEM中,对于NIST SP 800-38D:2007中规定的初始化向量IV
确定性构造,应使用8.2.1:IV
是两个字段的串联,称为固定字段
和调用字段
。
固定字段
应该标识物理设备,或者更一般地说,标识经过认证的加密功能实例的(安全)上下文。
调用字段
应标识该特定设备中经过认证的加密功能的输入集。
对于任何给定的键,任何两个不同的物理设备都不能共享相同的固定字段
,任何单个设备的两组不同的输入都不能共享相同的调用字段。
-
IV的长度应为96 bits(
12 octets
):len(IV) = 96。在此:- 前导(即最左边)64 bits(前8个八位元组)应保存
固定字段
。包含system title,见4.3.4; - 尾部(即最右边)32 bits应保存
调用字段
。调用字段应该是一个整数计数器。
- 前导(即最左边)64 bits(前8个八位元组)应保存
-
对于每个加密密钥EK(即块密码密钥),分别维护一个调用计数器(IC),用于经过认证的加密和经过认证验证的解密功能。以下规则适用:
- 密钥建立后,对应IC复位为0;
- 当使用认证加密功能时,使用相应的IC,然后加1。但是,当IC的最大值已经达到,任何后续调用认证的加密函数将返回一个错误,IC将不会增加;
- 当使用认证解密功能时,将验证IC的值。如果被验证的值小于可接受的最低值,则IC的验证失败——通过验证的解密函数也会失败。如果验证成功,则最低可接受值设置为已验证的IC的值加1。如果被验证的值等于最大值,则经过验证的解密函数将返回错误。
说明最大调用次数为232-1。
固定字段的位长度限制了可以为给定密钥实现经过验证的加密功能的不同物理设备的数量为264。
调用字段的位长度将使用任何给定的输入集调用经过验证的加密函数的次数限制为232,而不会违反唯一性要求
--------------------SLF NOTE Start--------------------
- 任意两个物理设备的固定字段不能相同(由systemtitle保证唯一),固定字段的位长将可以为给定密钥实现,验证加密功能的不同物理设备的数量限制为264。
- 对同一逻辑设备的任意两次请求的调用字段不能相同(每次请求递增),调用字段的位长将验证加密功能,调用次数限制为232
- 每个加密密钥(EK)都有两个相关联的调用计数器(IC),一个用于经过认证的加密函数,另一个用于经过认证的解密函数。
--------------------SLF NOTE End--------------------
9.2.3.3.7.4 The encryption key, EK
GCM使用一个密钥,即分组密码密钥。在DLMS/COSEM中,这被称为加密密钥,表示为EK。它的大小取决于安全套件(参见9.2.3.7),并且应该是:
- 对于安全套件0和1,128位(16字节):len(EK) = 128;
- 对于安全套件2,256位(32字节):len(EK) = 256;
密钥应均匀随机生成,或接近均匀随机生成,即每个可能的密钥(几乎)产生的可能性相等。因此,该键将是新键,即大概率地与之前的任何键不相等。密钥必须是保密的,并且只能用于GCM和所选的分组密码AES
。关于密钥建立和管理的附加要求在NIST SP 800-38D:2007, 8.1中进行了讨论。
9.2.3.3.7.5 The authentication key, AK
在DLMS/COSEM中,为了额外的安全性,还指定了标识为AK的AK。当存在时,它应成为附加认证数据(AAD)的一部分
。对于其长度和生成,应用与加密密钥(EK)相同的规则
9.2.3.3.7.6 Length of the authentication tag
认证标记的位长度,记作t,是一个安全参数。在安全套件0、1和2中,其值应为96 bits(12字节
)
9.2.3.3.8 AES key wrap
对于封装密钥数据,DLMS/COSEM选择了RFC 3394中指定的AES密钥封装算法。该算法设计用于封装或加密密钥数据。它在64 bits的块上运行。在封装之前,密钥数据被解析成n个64 bits块,密钥封装对n的唯一限制是n必须至少为2。
AES密钥封装可以配置为使用AES支持的三种密钥大小中的任何一种:128、192、256。
这两种算法分别是密钥封装
和密钥拆箱
。
密钥封装
过程的输入是KEK(密钥加密密钥)和要封装的明文(明文由n个64 bits块组成),其中包含被封装的关键数据。输出为(n+1)个64 bits的密文。
密钥拆箱
过程的输入是KEK(密钥加密密钥)和(n+1) 64 bits密文块(由先前封装的密钥组成)。它返回n个明文块,由解密密钥数据的n个64 bits块组成。
在DLMS/COSEM中,KEK的大小取决于安全套件(参见9.2.3.7),并且应该是:
- 对于安全套件0和1,128 bits(16字节):len(KEK) = 128;
- 对于安全套件2,256 bits(32字节):len(KEK) = 256。
9.2.3.4 Public key algorithms
9.2.3.4.1 General
一般来说,公钥加密系统使用难以解决的问题作为算法的基础。RSA算法是基于非常大的整数的质因数分解。椭圆曲线密码学(ECC)是基于求解椭圆曲线离散对数问题(ECDLP)的难度。与RSA相比,ECC提供了类似的安全级别,但大大减少了密钥大小。ECC特别适合嵌入式设备,因此它已被选择用于DLMS/COSEM。
在DLMS/COSEM中使用公钥算法用于以下目的:
- 通信伙伴的验证;
- xDLMS apdu和COSEM数据的数字签名;
- 密钥协商。
注1:以下文本摘自NIST SP 800-21:2005, 3.4。
非对称密钥算法(通常称为公钥算法)使用两个密钥:公钥和私钥,它们在数学上相互关联。公钥可以公开;如果数据要保留其加密保护,则私钥必须保密。即使这两个密钥之间存在关系,也不能从公钥中确定私钥。使用哪个密钥来应用或删除或检查保护取决于要提供的服务。例如,使用私钥计算数字签名,并使用公钥验证签名;对于那些也能够加密的算法,使用公钥执行加密,使用私钥执行解密。
注2:并非所有公钥算法都具有多种功能,例如生成数字签名和加密。在DLMS/COSEM中不使用非对称密钥算法进行加密。
非对称密钥算法主要用于数据完整性、身份验证和不可否认机制(即数字签名),以及密钥建立。
一些非对称密钥算法使用域参数,域参数是加密算法运行所必需的附加值。这些值在数学上是相互关联的。域参数通常是公开的,由协商在相当长的一段时间内使用。
非对称密钥算法的安全使用要求用户获得以下保证:
- 域参数有效性保证提供了域参数在数学上是正确的信心;
- 公钥有效性保证提供了公钥似乎是合适密钥的信心;和
- 私钥拥有保证提供了一种信心,即被认为是私钥所有者的一方确实拥有密钥。
一些非对称密钥算法可用于多种目的(例如,用于数字签名和密钥建立)。用于一种用途的密钥不得用于其他用途。
9.2.3.4.2 Elliptic curve cryptography
9.2.3.4.2.1 General
椭圆曲线密码学涉及在有限域上的椭圆曲线上的算术运算。椭圆曲线可以在任何数字域(即实数、整数、复数)上定义,尽管它们在密码学中最常用于有限素数域。
素数域上的椭圆曲线由满足下列方程的实数(x, y)组成:
y2=x3+ax+b
方程所有解的集合形成椭圆曲线。改变a和b会改变曲线的形状,这些参数的微小变化会导致(x, y)解集的重大变化。--------------------SLF NOTE Start--------------------
d:私钥
Q:公钥
Q=dG,其中G为基点
ECC 中涉及的椭圆曲线中,非常的出名的有,sepc256k1、Curve25519等.
ECC keys的长度取决于它采用了哪种椭圆曲线. 例如非常出名的开源项目,OpenSSL、mbedtls等,对于ECC通常默认的private keys 为256bit(32字节
),但最终取决于开发者使用哪一种椭圆曲线. 常见的有: 92-bit (curve secp192r1), 233-bit (curve sect233k1), 224-bit (curve secp224k1), 256-bit (curves secp256k1 and Curve25519), 283-bit (curve sect283k1), 384-bit (curves p384 and secp384r1), 409-bit (curve sect409r1), 414-bit (curve Curve41417), 448-bit (curve Curve448-Goldilocks), 511-bit (curve M-511), 521-bit (curve P-521), 571-bit (curve sect571k1) . 在mbedtls中对于选择的椭圆曲线,项目中直接提供了对应曲线的椭圆曲线参数.
椭圆曲线密码学基于数学上的椭圆曲线有限域提供了不同使用场景的相关算法.
- ECC 数字签名相关算法: ECDSA、EdDSA
- ECC 加密算法: ECIES、EEECC
- ECC秘钥协商算法: ECDH、X25519等
以上这些算法,都是以公钥和私钥的形式出现。私钥是一个整数,而公钥是对于椭圆曲线上的点(EC Point).对于ECC,知道私钥很容易计算出公钥,而知道公钥是很难算出私钥(这里面包含的知识是指数和对数的关系).
对于椭圆曲线: secp256k1, 给出了建议参数, a = 0; b=7,公式转化如下:y2=x3+7
对基于有限域的椭圆曲线,存在以下两点规则:
存在一组整数坐标: {x, y}, 0<= x < p,0<= y < p
坐落在椭圆曲线: y2 ≡ x3 + 7 (mod p)
{x, y}={5,8}在这条曲线上,因为(82)%17=(53+7)%17,此时p=17
--------------------SLF NOTE End--------------------
9.2.3.4.2.2 NIST recommended elliptic curves
FIPS PUB 186-4:2013推荐了素数域GF(p
)上的五条素数域椭圆曲线。其中,曲线P-256和P-384已被选择用于DLMS/COSEM,如表13所示。
DLMS security suite | Curve name in FIPS PUB 186-4:2013 | ASN.1 Object Identifier |
---|---|---|
Suite 0 | – | – |
Suite 1 | NIST curve P-256 | 1.2.840.10045.3.1.7 |
Suite 2 | NIST curve P-384 | 1.3.132.0.34 |
ASN.1对象标识符出现在证书的"AlgorithmIdentifier": Parameters下。见9.2.6.4.2。 |
9.2.3.4.3 Data conversions
9.2.3.4.3.1 Overview
本条款描述了用于在用于指定公钥算法的不同数据类型之间进行转换的数据转换原语:octet strings(OS)、bit strings (BS)、integers(I)、field elements ( 字段元素,FE)和elliptic curve points(椭圆曲线点,ECP)。DLMS/COSEM使用octet strings来表示公钥算法的元素,并使用这些数据类型之间的转换原语来表示octet strings。长度为d的octet strings,Md–1 Md–2…M0被编码为A-XDR OCTET STRING,其中最左边的八位位位组Md–1对应于OCTET STRING字符串的编码值的第一位。
9.2.3.4.3.2 Conversion between Bit Strings and Octet Strings (BS2OS)
将bit string转换为octet string的数据转换原语称为bit string到octet string转换原语,或BS2OS。它将bit string作为输入并输出octet string。将长度为L的bit string(bL-1bL-2...b0)转换为长度为d = ⌈L/8⌉ 的octet string(Md-1 Md-2...M0)。
转换在左边填入足够的零,使位数是8的倍数,然后将其分解为八位元组。
- 更确切地说,转换应如下:
- 当0≤i <d-1时,令八位元Mi = b8i+7 b8i+6...b8i;
- 最左边的OCTET(Md-1)应将其最左边的8d-L位设置为零;
- 最右边的8-(8d-L)bit应为bL-1bL-2...b8d-8。
--------------------SLF NOTE Start--------------------
- 高位在前,低位在后
- 补最高位的0
--------------------SLF NOTE End--------------------
9.2.3.4.3.3 Conversion between Octet Strings and Bit Strings (OS2BS)
将octet string转换为bit string的数据转换原语称为octet string到bit string转换原语,或OS2BS。它将octet string作为输入并输出bit string。
将长度为d的octet string(Md-1 Md-2...M0)转换为所需长度为L的bit string(bl-1 bl-2..b0),其中d= ⌈L/8⌉,且最左边octet string的最左边8d-L位为零。
- 更确切地说,转换应如下:
- 当0≤i<L-1时,令 字节 b8i+7 b8i+6...b8i=Mi;
- 最左边的8d-L bit应为0。
9.2.3.4.3.4 Conversion between Integers and Octet Strings (I2OS)
将Integers转换为octet string的数据转换原语称为Integers到octet string转换原语,或I2OS。它接受一个非负Integers x和octet string的期望长度d作为输入。长度d必须满足256d>x,否则输出"error"。I2OS输出相应的octet string。
- Integers x应以其唯一的进制(256)表示:
- x = xd-1·256d-1 + xd-2·256d-2 + x1 ·256 + x0;
- 当0≤i≤d-1时,0≤xi < 256;
- 当0≤i≤d-1时,Mi = xi。
输出字节串为Md-1 Md-2...M0。
--------------------SLF NOTE Start--------------------
举个例子 x=1996 d=2,则M1=07,M0=CC
--------------------SLF NOTE End--------------------
9.2.3.4.3.5 Conversion between Octet Strings and Integers (OS2I)
将octet string字符串转换为Integers的数据转换原语称为octet string到Integers转换原语,或OS2I。它以长度为d的八位串Md-1 Md-2...M0作为输入,输出相应的Integers x。对于长度为0的octet string,转换输出Integers 0。
- octet string被解释为以256为基数的非负Integers。更确切地说,转换应如下:
- 当0≤i≤d-1时,xi=Mi。
- x = xd-1·256d-1 + xd-2·256d-2 + x1 ·256 + x0;
9.2.3.4.3.6 Conversion between Field Elements and Octet Strings (FE2OS)
将Field Elements转换为Octet Strings的数据转换原语称为Field Elements到Octet Strings转换原语,或FE2OS。它接受一个Field Elements作为输入,并输出相应的Octet Strings。通过应用带参数L的I2OS转换原语,将域元素x∈Fp转换为长度d = ⌈log256 p⌉ 的Octet Strings(Md-1 Md-2...M0),其中
FE2OS(x) = I2OS(x, L)。
9.2.3.4.3.7 Conversion between Octet Strings and Field Elements (OS2FE)
将Octet Strings转换为Field Elements的数据转换原语称为Octet Strings到Field Elements转换原语,或OS2FE。它接受一个Octet Strings作为输入,并输出相应的Field Elements。将长度为d的的Octet Strings(Md-1 Md-2...M0)应用OS2I转换原语转换为Field Elements x ∈ Fp,其中:
OS2FE(x) = OS2I(x) mod p
--------------------SLF NOTE Start--------------------
Field Elements应该就是某个域范围内的一个值,比如域为0-9999,这个值可能就是3456。log25645768865=3.18098289749,所以长度就至少是4,结果为0x02BA60A1,其实就是把数字转换为16进制数用HEX表示。
--------------------SLF NOTE End--------------------
9.2.3.4.4 Digital signature
注:以下内容摘自NIST SP 800-21:2005, 3.4.1。
数字签名是书面签名的电子模拟,可用于向接收方或第三方证明消息是由发送方签署的(称为不可否认性的属性)
。还可以为存储的数据和程序生成数字签名,以便在以后的时间验证数据和程序的完整性。
数字签名验证签名数据的完整性和签名者的身份。数字签名在计算机中表示为bits 字符串,并使用数字签名算法计算,该算法提供生成和验证签名的功能。签名生成使用私钥生成数字签名。签名验证使用与私钥对应但不相同的公钥来验证签名。每个签名者拥有一个私钥对和一个公钥对。签名生成只能由签名者私钥的持有者执行。但是,任何人都可以通过使用签名者的公钥来验证签名。数字签名系统的安全性依赖于保持签名者私钥的保密性。因此,用户必须防范自己的私钥被非法获取。

图71描述了数字签名过程。在签名生成过程中使用哈希函数(见9.2.3.2)来获得待签名数据的压缩版本,称为消息摘要或哈希值。然后将消息摘要输入到数字签名算法中以生成数字签名。数字签名与签名数据(通常称为消息)一起发送给预期的验证者。消息和签名的验证者使用签名者的公钥验证签名。验证过程中也必须使用相同的哈希函数和数字签名算法。可以使用类似的程序为存储和传输的数据生成和验证签名。
--------------------SLF NOTE Start--------------------
关于什么是数字签名,可以看这篇文档 https://zhuanlan.zhihu.com/p/481974801
它用图片通俗易懂地解释了,"数字签名"(digital signature)和"数字证书"(digital certificate)到底是什么。
我对这些问题的理解,一直是模模糊糊的,很多细节搞不清楚。读完这篇文章后,发现思路一下子就理清了。为了加深记忆,我把文字和图片都翻译出来了。
鲍勃有两把钥匙,一把是公钥,另一把是私钥。
鲍勃把公钥送给他的朋友们----帕蒂、道格、苏珊----每人一把。
苏珊要给鲍勃写一封保密的信。她写完后用鲍勃的公钥加密,就可以达到保密的效果。
鲍勃收信后,用私钥解密,就看到了信件内容。这里要强调的是,只要鲍勃的私钥不泄露,这封信就是安全的,即使落在别人手里,也无法解密。
鲍勃给苏珊回信,决定采用"数字签名"。他写完后先用Hash函数,生成信件的摘要(digest)。
然后,鲍勃使用私钥,对这个摘要加密,生成"数字签名"(signature)。
鲍勃将这个签名,附在信件下面,一起发给苏珊。
苏珊收信后,取下数字签名,用鲍勃的公钥解密,得到信件的摘要。由此证明,这封信确实是鲍勃发出的。
苏珊再对信件本身使用Hash函数,将得到的结果,与上一步得到的摘要进行对比。如果两者一致,就证明这封信未被修改过。
复杂的情况出现了。道格想欺骗苏珊,他偷偷使用了苏珊的电脑,用自己的公钥换走了鲍勃的公钥。此时,苏珊实际拥有的是道格的公钥,但是还以为这是鲍勃的公钥。因此,道格就可以冒充鲍勃,用自己的私钥做成"数字签名",写信给苏珊,让苏珊用假的鲍勃公钥进行解密。
后来,苏珊感觉不对劲,发现自己无法确定公钥是否真的属于鲍勃。她想到了一个办法,要求鲍勃去找"证书中心"(certificate authority,简称CA),为公钥做认证。证书中心用自己的私钥,对鲍勃的公钥和一些相关信息一起加密,生成"数字证书"(Digital Certificate)。
鲍勃拿到数字证书以后,就可以放心了。以后再给苏珊写信,只要在签名的同时,再附上数字证书就行了。
苏珊收信后,用CA的公钥解开数字证书,就可以拿到鲍勃真实的公钥了,然后就能证明"数字签名"是否真的是鲍勃签的。
下面,我们看一个应用"数字证书"的实例:https协议。这个协议主要用于网页加密。
首先,客户端向服务器发出加密请求。
服务器用自己的私钥加密网页以后,连同本身的数字证书,一起发送给客户端。
客户端(浏览器)的"证书管理器",有"受信任的根证书颁发机构"列表。客户端会根据这张列表,查看解开数字证书的公钥是否在列表之内。
如果数字证书记载的网址,与你正在浏览的网址不一致,就说明这张证书可能被冒用,浏览器会发出警告。
如果这张数字证书不是由受信任的机构颁发的,浏览器会发出另一种警告。
如果数字证书是可靠的,客户端就可以使用证书中的服务器公钥,对信息进行加密,然后与服务器交换加密信息。
数字签名不能用来加解密
--------------------SLF NOTE End--------------------
9.2.3.4.5 Elliptic curve digital signature (ECDSA)
DLMS/COSEM采用FIPS PUB 186-4:2013中规定的椭圆曲线数字签名(ECDSA)算法。NSA1提供了实现指南。
在DLMS/COSEM中使用的椭圆曲线和算法如下:
- 在Security Suite 1的情况下,使用SHA-256哈希算法的椭圆曲线P-256;
- 在Security Suite 2的情况下,使用SHA-384哈希算法的椭圆曲线P-384。
生成ECDSA数字签名的输入资料如下:
- 待签名的消息M;
注1:在DLMS/COSEM上下文中,"Message"可以是xDLMS APDU(见9.2.7.2)或COSEM data(见9.2.7.5)
- 签署人的私钥,d;
输出是M上的ECDSA签名(r,s)。
--------------------SLF NOTE Start--------------------
过程:已知椭圆曲线参考点G、私钥d,信息M以及产生一个随机数k
- P=k×G(×是椭圆曲线上的点乘)
- P点的横坐标作为r(20字节)
- 对消息Msg:z=SHA1(M)(z为20字节)
- s=k-1(z+d×r)mod p(k-1是k的模的乘法逆元)
最终的输出的是两元数组(r,s) 40个字节
--------------------SLF NOTE End--------------------
在DLMS/COSEM中应使用纯格式:签名(r, s)被编码为八位字节字符串R||S
,即作为八位字节字符串R=I2OS(R,L)和S=I2OS(S,L)与L=⌈log256n⌉的连接。因此,签名的长度固定为2L个八位字节。
其中n为椭圆曲线基点G的阶数。I2OS是整数到八进制字符串转换原语。见9.2.3.4.3。
- 核实数字签名生成的ECDSA的输入如下:
- 签名消息M';
- 收到的ECDSA签名(r',s');
- 签署人的真实公钥Q。
生成和验证签名的过程应按照NSA1 3.4的规定进行。
--------------------SLF NOTE Start--------------------
过程:已知(r',s'),公钥Q,参考点G以及消息M'
z=SHA(M')
P=S-1×
z×
G+S-1×R×Q(第1,2个是椭圆曲线上的点乘算法)
然后判断P的x坐标是否于r相等,如果相等则这个签名有效,否则是无效的
有效的含义即这个M'认为是真实且可信的
网上找的ECDSA签名验证证书的C#源码,简洁明了,源代码地址 https://www.cnblogs.com/darkif/p/16502884.html ,如有侵权,联系作者(1781479820@qq.com)删除
using System;
using System.IO;
using System.Text;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;
namespace security_sandbox
{
class Program
{
static void Main(string[] args)
{
var certificateString = @"-----BEGIN CERTIFICATE-----
MIIB4TCCAYegAwIBAgIUKt0WdaKI2eRXBO2nVk+OF6AZqHMwCgYIKoZIzj0EAwIw
RTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAgFw0yMDA1MDcxMzM2MTNaGA8yMTIwMDQx
MzEzMzYxM1owRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAf
BgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDBZMBMGByqGSM49AgEGCCqG
SM49AwEHA0IABO39ccEC+Zv1HDeMy/s7JculdYN/8DXC+U3Qn1rdF351H4NMfkbC
H9bnqwZ4a5oR9HDfaNMX14OQd4VERZV1bhGjUzBRMB0GA1UdDgQWBBRGuUmsyB2h
JCXMRTVMRTcdoWZQaDAfBgNVHSMEGDAWgBRGuUmsyB2hJCXMRTVMRTcdoWZQaDAP
BgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA0gAMEUCIGG8tQZlh7aJaI34Y7jq
44SmSc/ule9MgjIX+Gg+i5vwAiEA9Jb/304KO4t9OMqFMQeWZXIHdzhDFBwx7FWz
78+UsnY=
-----END CERTIFICATE-----";
var pemreader = new PemReader(new StringReader(certificateString));
var cert = (X509Certificate)pemreader.ReadObject();
// Alternatively, load the public key directly
var pubkeyString =
@"-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE7f1xwQL5m/UcN4zL+zsly6V1g3/w
NcL5TdCfWt0XfnUfg0x+RsIf1uerBnhrmhH0cN9o0xfXg5B3hURFlXVuEQ==
-----END PUBLIC KEY-----";
pemreader = new PemReader(new StringReader(pubkeyString));
var pubkey = (AsymmetricKeyParameter)pemreader.ReadObject();
var data = "Hello";
var signature = Convert.FromBase64String("MEUCIQD5593C/NBhHA1DILT72gjhGj/lKjom9vYP+JbuypBrxQIgNAjYT1LihEpPbUhe1n9ccUHQvw676bGqOTEU/25qcRQ=");
// Verify using the public key
var signer = SignerUtilities.GetSigner("SHA-256withECDSA");
signer.Init(false, pubkey);
signer.BlockUpdate(Encoding.ASCII.GetBytes(data), 0, data.Length);
var success = signer.VerifySignature(signature);
if (success) {
Console.WriteLine("Signature verified successfully using public key");
} else {
Console.WriteLine("Failed to verify signature using public key");
}
// Verify using the certificate - the certificate's public key is extracted using the GetPublicKey method.
signer.Init(false, cert.GetPublicKey());
signer.BlockUpdate(Encoding.ASCII.GetBytes(data), 0, data.Length);
success = signer.VerifySignature(signature);
if (success) {
Console.WriteLine("Signature verified successfully using certificate");
} else {
Console.WriteLine("Failed to verify signature using certificate");
}
}
}
}
有关椭圆曲线验证签名的 这篇文档讲的特别详细 https://blog.csdn.net/weixin_43586667/article/details/122766815
--------------------SLF NOTE End--------------------
9.2.3.4.6 Key agreement
9.2.3.4.6.1 Overview
密钥协商允许两个实体联合计算共享密钥,并从中获得密钥材料。另见NIST SP 800-56A Rev.2:2013。
对于DLMS/COSEM,从NIST SP 800-56A Rev.2:2013中选择了三种椭圆曲线密钥协商方案:
- 短期统一模型C(2e,0s,ECC CDH)方案;
- One-Pass Diffie-Hellman C(1e,1s,ECC CDH)方案;
- 静态统一模型C(0e,2s,ECC CDH)方案。
对于NSA套件B,已选择前两个方案
--------------------SLF NOTE Start--------------------
ECC在C#中使用详解 https://blog.csdn.net/lgj123xj/article/details/130227771
--------------------SLF NOTE End--------------------
9.2.3.4.6.2 The Ephemeral Unified Model C(2e, 0s, ECC CDH) scheme
该方案用于DLMS/COSEM客户端和服务器之间,以就master key、global encryption keys和/或authentication key达成一致。客户端扮演U方,服务器扮演V方。该过程由"Security setup"接口类的方法支持;参见DLMS UA 1000-1 Ed.12:2017,4.4.7。
各方根据域参数D生成临时密钥对。各方交换临时公钥,然后使用域参数
、它们的临时私钥
和另一方的临时公钥
计算共享密钥Z。密钥材料是使用9.2.3.4.6.5中规定的密钥推导函数从共享密钥Z和其他输入中推导出来的。
NIST SP 800-56A Rev.2:2013,6.1.2.2和NSA2,3.1中详细规定了该过程,如下图72和表14所示。

该图再现了NSA2,图1
U1:U使用它的临时私钥de,U和V的临时公钥Qe,V组成一个共享密钥。
U2:U使用共享密钥调用密钥派生函数。
V1:V使用它的临时私钥de,V和U的临时公钥Qe,U组成一个共享密钥。
V2:V使用共享密钥调用密钥派生函数
先决条件:
a)甲乙双方各有一套相同的域名参数,D.D应从两套域名参数中任选一套,详见附件a;
b)双方已同意使用NIST串联KDF;见9.2.3.4.6.5。SHA-256是用于P-256的域参数的哈希函数,SHA-384是用于P-384的域参数的哈希函数;
c)在密钥协商过程之前或过程中,双方在密钥协商方案中获得与另一方相关联的标识符。
注:请参见NIST SP 800-56A Rev. 2: 2013和NSA2,以获取有关域参数有效性保证、私钥和公钥有效性以及私钥拥有保证的更多信息。
Party U | Party V | |
---|---|---|
域参数 | (q, FR, a, b{,SEED}, G, n, h)由安全套件确定 | (q, FR, a, b{,SEED}, G, n, h)由安全套件确定 |
Static data | N/A | N/A |
短期数据 | 短期私钥,de,U 短期公钥,Qe,V | 短期私钥,de,U 短期公钥,Qe,V |
Computation | 通过使用de,U和Qe,V调用ECC CDH来计算Z | 通过使用de,V和Qe,U调用ECC CDH来计算Z |
派生密钥材料 | 1.计算kdf(Z,OtherInput) 2.销毁Z | 1.计算kdf(Z,OtherInput) 2.销毁Z |
注:本表基于NIST SP 800-56A Rev.2:2013表18和NSA2表1。 |
选择C(2e, 0s)方案的基本原理在NIST SP 800-56A Rev. 2: 2013, 8.2中有详细说明。
在C.1中进一步解释了该方案在DLMS/COSEM中的使用。
9.2.3.4.6.3 The One-Pass Diffie-Hellman C(1e, 1s, ECC CDH) scheme
该方案用于DLMS/COSEM服务器和另一方就临时加密密钥达成协议,以保护xDLMS apdu或COSEM数据。发送方(发送方)扮演U方,另一方(接收方)扮演V方。
注1:术语发送方和接收方是指通用加密APDU的字段。
对于该方案,U方生成一个临时密钥对;V方只有一个静态密钥对。U方以可信的方式(例如从可信CA签名的证书中)获取V方的静态公钥,并将自己的临时公钥发送给V方。双方分别使用自己的私钥和对方的公钥获得共享密钥Z。各方使用9.2.3.4.6.5中规定的密钥派生方法从共享密钥Z和其他输入中派生密钥材料。
该过程在NIST SP 800-56A Rev. 2: 2013, 6.2.2.2和NSA2, 3.2中有详细规定,如图73和表15所示。
--------------------SLF NOTE Start--------------------
- 和上面的类似,主要是静态动态公钥的区别,就是不需要服务端把动态公钥给客户端,客户端可以通过预先导入的证书(可信 CA 签名)获得对方的静态公钥
- 全程只需要发送一次公钥
--------------------SLF NOTE End--------------------

该图再现了NSA2,图2
U1:U使用它的临时私钥de,U和V的临时公钥Qs,V组成一个共享密钥。
U2:U使用共享密钥调用密钥派生函数。
V1:V使用它的临时私钥ds,V和U的临时公钥Qe,U组成一个共享密钥。
V2:V使用共享密钥调用密钥派生函数
先决条件:
a)U,V双方应各有一套相同的域参数的副本,D. D应从两套域参数中选择一套域参数,见附件a;
b)V方已被指定为9.2.6.2中使用域参数集D生成的静态密钥对的所有者;
c)双方同意使用NIST串联KDF,见9.2.3.4.6.5。SHA-256是用于P-256的域参数的哈希函数,SHA-384是用于P-384的域参数的哈希函数;
D)在密钥协商过程之前或过程中,双方在密钥协商方案中获得与另一方相关联的标识符。U方获取与V方标识符绑定的静态公钥。此静态公钥应以受信任的方式获得(例如,从受信任的CA签署的证书中获得)。
注2:另见NIST SP 800-56A Rev. 2: 2013和NSA2,以获取关于域参数有效性保证、私钥和公钥有效性以及私钥拥有保证的更多信息
Party U | Party V | |
---|---|---|
域参数 | (q, FR, a, b{,SEED}, G, n, h)由安全套件确定 | (q, FR, a, b{,SEED}, G, n, h)由安全套件确定 |
Static data | N/A | 静态私钥,ds,V 静态公钥,Qs,V |
Ephemeral data | 短期私钥,de,U 短期公钥,Qe,U | N/A |
Computation | 通过使用de,U和Qs,V调用ECC CDH来计算Z | 通过使用ds,V和Qe,U调用ECC CDH来计算Z |
派生密钥材料 | 1.计算kdf(Z,OtherInput) 2.销毁Z | 1.计算kdf(Z,OtherInput) 2.销毁Z |
注:本表基于NIST SP 800-56A Rev.2:2013表24和NSA2表2。 |
选择该方案的基本原理在NIST SP 800-56A Rev. 2: 2013, 8.4中有详细说明。
在C.2中进一步解释了该方案在DLMS/COSEM中的使用。
9.2.3.4.6.4 The Static Unified Model C(0e, 2s, ECC CDH) scheme
该方案用于DLMS/COSEM服务器和另一方就临时加密密钥达成协议,以保护xDLMS apdu或COSEM数据。发送方(数据源)扮演U方,另一方(接收方)扮演V方。
注1:术语发送方和接收方是指general-ciphering APDU的字段。
在这种情况下,各方仅使用静态密钥对。双方获取对方的静态公钥。一个nonce, NonceU,由U方发送给V方,以确保派生的密钥材料在每次密钥建立协商中都是不同的。
双方使用自己的静态私钥和对方的静态公钥派生出共享密钥Z。使用9.2.3.4.6.5中规定的密钥派生函数、共享密钥Z、U和V的标识符以及nonce导出密钥材料。
流程如图74和表16所示。

该数据基于NIST SP 800-56A Rev. 2: 2013,图15。
U1:U使用它的静态私钥ds,U和V的静态公钥Qs,V组成一个共享密钥。
U2:U使用共享密钥和NonceU调用密钥派生函数
V1:V使用它的静态私钥ds,V和U的静态公钥Qs,U组成一个共享密钥。
V2:V使用共享密钥和NonceU调用密钥派生函数
先决条件:
a)双方应各有一套相同的域参数的真实副本,D、D必须从两套域参数中任选一套,见附件a;
b)各方已被指定为9.2.6.2中使用域参数集合D生成的静态密钥对的所有者;
c)双方同意使用NIST串联KDF,见9.2.3.4.6.5。SHA-256是用于P-256的域参数的哈希函数,SHA-384是用于P-384的域参数的哈希函数;
D)在密钥协商过程之前或过程中,各方均应获得密钥协商方案期间与另一方相关联的标识符;
E)双方获取对方与标识符绑定的静态公钥。这些静态公钥应该以可信的方式获得(例如,从可信CA签名的证书中获得)。
注2:另见NIST SP 800-56A Rev. 2: 2013,有关域参数的有效性保证、私钥和公钥的有效性以及私钥拥有的保证的更多信息。
Party U | Party V | |
---|---|---|
域参数 | (q, FR, a, b{,SEED}, G, n, h)由安全套件确定 | (q, FR, a, b{,SEED}, G, n, h)由安全套件确定 |
Static data | 静态私钥 ds,U 静态公钥 Qs,U | 静态私钥 ds,V 静态公钥 Qs,V |
Ephemeral data | NonceU | |
Computation | 通过使用ds,U和Qs,V调用ECC CDH来计算Z | 通过使用ds,V和Qs,U调用ECC CDH来计算Z |
派生密钥材料 | 1.通过使用NonceU来计算派生密钥材料 2.销毁Z | 1.通过使用NonceU来计算派生密钥材料 2.销毁Z |
注1:本表基于NIST SP 800-56A Rev. 2: 2013,表26。 | ||
注2:在相同的两方之间的所有C(0e,2s)密钥建立交易中,Z的值是相同的,因此,如果它被泄露,那么在这两个使用相同静态密钥对的相同实体之间的过去,当前和未来的C(0e, 2s)密钥协商交易中派生的所有密钥材料也可能被泄露。任何未"归零"的共享密钥Z都应以与私钥相同的安全保护进行存储和使用。 |
选择该方案的基本原理在NIST SP 800-56A Rev. 2: 2013, 8.5中有详细说明。
在C.3中进一步解释了该方案在DLMS/COSEM中的使用。
--------------------SLF NOTE Start--------------------
和上面的类似,将动态公钥变成了静态公钥,不需要发送公钥,只需要Nonce,Nonce用于计算密钥材料,保证每次生成的密钥材料不同。
--------------------SLF NOTE End--------------------
9.2.3.4.6.5 Key Derivation Function – The NIST Concatenation KDF
应使用NIST SP 800-56A Rev. 2: 2013, 5.8.1.1和NSA2,Clause 5中规定的NIST串联KDF。具体如下:
函数调用:kdf(Z, OtherInput)
其中OtherInput
由keydatalen
和OtherInfo
组成。
具体实现相关的参数:
a) hashlen:一个整数,表示哈希函数(hash)输出的长度(以bit为单位),用于导出密钥材料块。在安全套件1的情况下,这将是256
(SHA-256),在安全套件2的情况下,这将是384
(SHA-384);
b) max_hash_inputlen:一个整数,表示输入到哈希函数的位串的最大长度(以bit为单位)。
SHA-256的max_hash_inputlen长度小于264bit,SHA-384的max_hash_inputlen长度小于2128bit。
功能:H:哈希函数:安全套件1为SHA-256,安全套件2为SHA-384。
输入:
c) Z:表示共享密钥Z的字节串;
d) keydatalen:表示要生成的密钥材料长度(以bit为单位)的整数:安全套件1为128位,安全套件2为256位;
e) OtherInfo:一个bit字符串,等于以下连接:
AlgorithmID || PartyUInfo || PartyVInfo {||SuppPubInfo}{||SuppPrivInfo}
- 其中子字段定义如下:
- AlgorithmID:一个bit串,指示如何解析派生密钥材料,以及将使用哪种算法派生密钥材料。见表18;
- PartyUInfo:包含公开信息的bit串,该信息由使用此KDF的应用程序要求由U方提供给密钥派生过程;
- PartyVInfo:包含公共信息的bit串,该信息由使用此KDF的应用程序要求由V方提供给密钥派生过程;
- suppPubinfo(可选):包含额外的、相互知道的公共信息的bit串。
DLMS/COSEM中未使用
。 - suppPrivinfo(可选):包含额外的,相互知道的私有信息的bit串(例如,通过单独通道通信的共享秘密对称密钥)。
DLMS/COSEM中未使用
。
每个子字段和子字符串的格式和内容如表17所示。
SubfieldSubstring | Key agreement scheme | Length in octets | Value | ||
---|---|---|---|---|---|
C(2e, 0s) | C(1e, 1s) | C(0e, 2s) | |||
Format | |||||
AlgorithmID | Fixed | Fixed | Fixed | 7 | See Table 18 |
PartyUinfo | Fixed | Fixed | Variable | 8+n | – |
IDU | Fixed | Fixed | Fixed | 8 | originator-system-title |
NonceU | – | – | Variable | n | Datalen = transaction-id的长度,应为1字节。 Data = transaction-id的值 |
PartyVInfo | Fixed | Fixed | Fixed | 8 | – |
IDV | Fixed | Fixed | Fixed | 8 | recipient-system-title |
"originator-system-title"、"transaction-id"和"recipient-system-title"是general-ciphering APDU的字段 |
在DLMS/COSEM中,密钥派生为给定目的提供单个密钥。长度由安全套件决定。算法应如表18所示。参见9.4.2.2.4。
Algorithm | COSEM cryptographic algorithm ID | Encoded value |
---|---|---|
AES-GCM-128 | 2.16.756.5.8.3.0 | 60 85 74 05 08 03 00 |
AES-GCM-256 | 2.16.756.5.8.3.1 | 60 85 74 05 08 03 01 |
AES-WRAP-128 | 2.16.756.5.8.3.2 | 60 85 74 05 08 03 02 |
AES-WRAP-256 | 2.16.756.5.8.3.3 | 60 85 74 05 08 03 03 |
9.2.3.5 Random number generation
提供强随机数生成器(Strong random number generator, RNG)来生成DLMS/COSEM中使用的各种算法所需的随机数。RNG最好是不确定的。如果非确定性RBG不可用,系统应利用足够的熵为确定性RNG创建高质量的种子。
9.2.3.6 Compression
压缩不涉及加密,是对xDLMS APDU的一种转换。由于这个原因,并且由于它与对称密钥加密一起控制,因此在这里指定它。
压缩可以应用于COSEM数据或xDLMS APDU。这个过程可以与对称密钥加密相结合。见9.2.7.2.4.7和9.2.7.2.4.8。压缩算法应符合ITU-T V.44:2000的规定。选择此算法是为了满足以下要求:
- 处理负载低;
- 内存要求低;
- 低延迟。
压缩的使用由9.2.7.2.4中规定的Security Control字节的第7位
指示。
9.2.3.7 Security suite
安全套件确定各种加密原语可用的加密算法集和密钥长度。
DLMS/COSEM安全套件(见表19)基于NSA Suite B,包括用于认证、加密、密钥协商、数字签名和哈希的加密算法。
- 认证和加密:应按照FIPS PUB 197中规定的高级加密标准(AES)使用,密钥长度为128位和256位。AES应与NIST SP 800-38D:2007中规定的Galois/Counter Mode(GCM)操作一起使用;
- 数字签名:椭圆曲线数字签名算法(ECDSA)应按照指定的FIPS PUB 186-4:2013和NSA1使用曲线P-256或P-384;
- 密钥协商
- Ephemeral Unified Model C(2e, 0s, ECC CDH)方案,见9.2.3.4.6.2;
- One-Pass Diffie-Hellman C(1e, 1s, ECC CDH)方案,见9.2.3.4.6.3;和
- 静态统一模型C(0e, 2s, ECC CDH)方案,参见9.2.3.4.6.4,应使用椭圆曲线P-256或P-384。
- 哈希:安全哈希算法(SHA) SHA-256和SHA-384应按照FIPS PUB 180-4:2012中指定的方式使用。
此外,还提供了密钥封装和压缩算法。
Security Suite Id | Security suite name | Authenticated encryption | Digital signature | Keyagreement | Hash | Key- transport | Compression |
---|---|---|---|---|---|---|---|
0 | AES-GCM-128 | AES-GCM-128 | – | – | – | AES-128key wrap | – |
1 | ECDH-ECDSA- AES-GCM-128-SHA-256 | AES-GCM-128 | ECDSAwith P-256 | ECDHwith P-256 | SHA- 256 | AES-128key wrap | V.44 |
2 | ECDH-ECDSA- AES-GCM-256-SHA-384 | AES-GCM-256 | ECDSAwith P-384 | ECDHwith P-384 | SHA- 384 | AES-256key wrap | V.44 |
All other reserved | – | – | – | – | – | – | – |
9.2.4 Cryptographic keys – overview
加密密钥是与加密算法一起使用的参数,该算法确定其操作的方式是,知道密钥的实体可以复制或反转操作,而不知道密钥的实体则不能。在DLMS/COSEM中,操作示例包括:
- 明文到密文的转换;
- 密文到明文的转换;
- 验证码(MAC)的计算和验证;
- 密钥封装;
- 应用和验证数字签名;
- 密钥协商。
对称密钥算法使用的密钥在9.2.5中指定。
公钥算法使用的密钥在9.2.6中指定。
9.2.5 Key used with symmetric key algorithms
9.2.5.1 Symmetric keys types
对称密钥的分类:
-
a)按目的分类
- key encrypting key (KEK)用于
加密其他对称加密密钥
,例如master key - encryption key 用于 AES-GCM 算法的块加密
- authentication key 用于AES-GCM 算法的 AAD
- key encrypting key (KEK)用于
-
b)按生命周期分类
- 打算使用较长时间的静态密钥。在 DLMS/COSEM 中,它们可能是:
- 全局密钥,可用于在相同合作伙伴之间重复建立的多个AA。全局密钥可以是单播加密密钥(GUEK)、广播加密密钥(GBEK)或AK(GAK);
- 专用密钥,可用于在两个合作伙伴之间建立的单个AA期间重复使用的密钥。因此,其生命周期与AA的生命周期相同。专用密钥只能是
单播加密密钥(UEK)
。
- 临时密钥通常用于一个AA内的单个交换。
- 打算使用较长时间的静态密钥。在 DLMS/COSEM 中,它们可能是:
--------------------SLF NOTE Start--------------------
- InitiateRequest APDU 和 AARQ 是什么关系?答:见 12.3 Table 133最后, InitiateRequest APDU 是 AARQ 中 user-information字段的一部分,是可以加密的
- 专用密钥 由 AARQ APDU 中的 InitiateRequest APDU 携带,这个InitiateRequest APDU 本身 要被全局单播密密钥(GUEK)加密,AARE中的 InitiateResponse APDU 也要用相同的方式加密。
--------------------SLF NOTE End--------------------
关于对称密钥的生成和分发,请参见NIST SP 800-57:2012, 8.1.5.2。
使用表20中所示的方法之一,在每个DLMS/COSEM客户机-服务器之间建立主密钥和全局密钥。应定期更新,见9.2.3.3.7.3和9.2.5.6。
专用密钥由DLMS/COSEM客户端生成,并在xDLMS InitiateRequest APDU的专用密钥字段中传输到服务器,由AARQ APDU的用户信息字段携带
。当专用密钥存在时,xDLMS InitiateRequest APDU将使用AES-GCM-128/256算法、GUEK,AK进行认证和加密。由AARE APDU user-information 字段携带的xDLMS InitiateResponse APDU也要采用同样的方式进行加密和认证。当使用专用密钥时,security control 字节的密钥设置位(见表37)不相关,应设置为零。
AARQ 和 AARE APDUs 本身不受保护
表20总结了对称密钥类型、它们的用途、建立它们的方法以及它们在不同APDU和不同实体之间的使用。
Key type | 目的 | Key establishment | Use |
---|---|---|---|
Master key, KEK1) | 密钥加密密钥(KEK): - (新)主密钥 - 全局加密或AK - 临时加密密钥 | Out of band | 可识别为客户端-服务器之间general-ciphering APDUs的KEK ,见表21 |
密钥封装 | |||
密钥协商3) | |||
Global unicast encryption key, GUEK 2) | 单播分组密码的密钥 - xDLMS APDUs和/或 - COSEM 数据 | 密钥封装 | - service-specific的全局加密 APDU客户端-服务器 - general-glo-ciphering APDU 客户端-服务器 - general-ciphering APDU 客户端-服务器 - "数据保护"对象保护参数 |
密钥协商3) | |||
Global broadcast encryptionkey, GBEK 2) | 广播分组密码的密钥 - xDLMS APDUs和/或 - COSEM 数据 | 密钥封装 | |
(Global)Authentication key, GAK 2) | 部分AAD用于xDLMS apdu和/或COSEM数据的加密过程 | 密钥封装 | 客户端-服务器和第三方-服务器之间的所有apdu |
密钥协商3) | |||
Dedicated key (unicast) | 在已建立的AA内,单播xDLMS apdu的分组密码密钥 | xDLMS Initiate.request APDU中的密钥传输 | - service-specific dedicated ciphering APDU客户端-服务器 - general-ded-ciphering APDU客户端-服务器 在AA的生命周期内 |
Ephemeral encryption key | 分组密码密钥用于: - xDLMS APDUs和/或 - COSEM 数据 | 密钥封装 | - general-ciphering APDU 客户端-服务器 - "数据保护"对象保护参数 |
分组密码密钥用于: - xDLMS APDUs和/或 - COSEM 数据 | 密钥协商4) | - general-ciphering APDU 客户端-服务器或第三方-服务器 - "数据保护"对象保护参数 | |
1)由"Security setup"对象持有。不同的AA可以使用相同或不同的"Security setup"对象。 |
9.2.5.2 Key information with general-ciphering APDU and data protection
当general-ciphering APDU用于保护xDLMS APDU或COSEM数据时,发送方发送关于已经/将要用于加密/解密xDLMS APDU/COSEM数据的密钥的必要信息,以及加密后的xDLMS APDU/COSEM数据。
所需的关键信息总结于表21,并在9.2.5.3、9.2.5.4和9.2.5.5中作了进一步规定。
Key information choices | Comment | |
---|---|---|
key-Info | ||
identified-key | S | EK已识别 |
key-id | M | |
global-unicast-encryption-key | S | GUEK |
global-broadcast-encryption-key | S | GBEK |
wrapped-key | S | EK使用密钥封装进行传输 |
kek-id | M | |
master-key | M | 标识用于封装密钥加密数据的密钥。0 =主密钥(KEK) |
key-ciphered-data | M | 用KEK封装的随机生成密钥 |
agreed-key | S | 密钥由双方使用以下任一种方式达成一致: - One-Pass Diffie-Hellman C(1e,1s,ECC CDH)方案见9.2.3.4.6.3;或 -静态统一模型C(0e,2s,ECC CDH)方案见9.2.3.4.6.4。 |
key-parameters | M | 密钥协商方案标识符: 0x01: C(1e, 1s ECC CDH) 0x02: C(0e,2s ECC CDH) 其他所有的保留。 |
key-ciphered-data | M | -在C(1e,1s,ECC CDH)方案的情况下:用U的私有数字签名密钥签名U的临时密钥协商密钥对的公钥Qe,U。 -在C(0e,2s,ECC CDH)方案的情况下:长度为零的Octetstring。在这种情况下,U方必须提供一个nonce(NonceU)。见9.2.3.4.6.4和9.2.3.4.6.5。 |
M: 强制性的 (part of a SEQUENCE) S: 可选的 (part of a CHOICE) 对于ASN.1规范, see 9.5. | ||
Note:使用Key identification限制了在客户端和服务器之间交换受保护的xDLMS apdu/COSEM数据,因为GUEK和GBEK不得向客户端和服务器以外的任何一方披露。 |
--------------------SLF NOTE Start--------------------
- 可以识别为客户端和服务器之间的KEK通用加密APDU
- 当 general-ciphering APDU 用于保护
xDLMS APDU
或COSEM
数据时,发送方不仅要发送加密后的 xDLMS APDU/COSEM
数据,同时也要发送密钥的必要信息,该信息已经或将用于 加密/解密 xDLMS APDU/COSEM数据,包括EK、AK、MK等
--------------------SLF NOTE End--------------------
9.2.5.3 Key identification
所识别的密钥可以是全局单播加密密钥(GUEK)或全局广播加密密钥(GBEK)。在这种情况下,security control字节(SC
)的密钥设置位(见表37)不相关,应设置为零。
9.2.5.4 Key wrapping
密钥封装可用于建立静态或临时对称密钥。
该算法为9.2.3.3.8中规定的AES密钥封装算法。KEK是主密钥。因此,此方法只能在共享主密钥的各方之间使用,即在客户端和服务器之间。
可以使用密钥封装建立的静态密钥如下:
- the master key, KEK; and/or
- the global unicast encryption key GUEK; and/or
- the global broadcast encryption key GBEK; and/or
- the (global) authentication key, GAK.
要使用密钥封装建立这些静态密钥,客户端应首先生成密钥,然后通过调用"Security setup"对象的key_transfer方法将其传输到服务器,请参见DLMS UA 1000-1 Ed.12:2017,4.4.7。方法调用参数应携带key_id和wrapped key。承载调用方法的服务和方法调用参数的APDU应根据安全策略和访问权限的要求进行保护。
可在项目特定配套规范中规定所需的防护等级。
为了使用密钥封装来建立临时密钥
,xDLMS APDU或COSEM数据的发起者随机生成临时密钥
。该临时密钥
应使用AES key wrap算法和KEK进行封装,并应与使用临时密钥
加密的xDLMS APDU或COSEM数据一起发送给接收方。收件人应打开临时密钥
,然后使用临时密钥
进行解密
9.2.5.5 Key agreement
密钥协商
可以用于在服务器和客户端之间建立静态密钥,或者在服务器和客户机或第三方之间建立临时密钥。不同的密钥协商
方案可用于建立不同的密钥。
客户端和服务器可以使用Ephemeral Unified Model C(2e,0s, ECC CDH) scheme来商定:
- the master key, KEK; and/or
- the global unicast encryption key GUEK; and/or
- the global broadcast;and/or encryption key GBEK; and/or
- the (global) authentication key, GAK.
该方案由"Security setup"接口类的key_agreement方法支持,请参见DLMS UA 1000-1 Ed.12:2017,4.4.7。方法调用参数携带9.2.3.4.6.2中规定的必要参数。承载调用方法的服务以及方法调用参数的APDU应根据安全策略和访问权限的要求进行保护。另见附件C。
可在项目特定配套规范中规定所需的防护等级。
要使用密钥协商
建立临时加密密钥(用作块密码密钥),有两种方案可用:
- 9.2.3.4.6.3中规定的One-Pass Diffie-Hellman C(1e,1s,ECC CDH)方案;除非项目特定配套规范中另有规定,否则应使用C(1e,1s ECC CDH)方案。
- 9.2.3.4.6.4中规定的静态统一模型C(0e,2s,ECC CDH)方案
9.2.5.6 Symmetric key cryptoperiods
对称密钥加密周期
应在项目特定配套规范中确定。NIST SP 800-57:2012第1部分5.3.5对称密钥使用周期和加密周期以及5.3.6特定密钥类型的加密周期建议中给出了建议。
9.2.6 Keys used with public key algorithms
9.2.6.1 Overview
- 非对称加密算法密钥分类:
- 按目的:数字签名、密钥协商
- 按生命周期:静态密钥、临时密钥
数字签名 | |||
---|---|---|---|
密钥类型 | 签署人 | 验证人 | Use |
数字签名 密钥对 | 私钥 | 公钥 | 签署人使用私钥计算数字签名: -在xDLMS APDU上 -关于COSEM数据 -在临时的公钥协议密钥上 验证人使用公钥验证数字签名 -在xDLMS APDU上 -关于COSEM数据 -基于接收到的临时公钥协议密钥 |
密钥协商 | |||
密钥类型 | 用户 | 服务器 | Use |
临时密钥 协商密钥对 | 私钥 公钥 | 私钥 公钥 | 在临时统一模型C(2e,0s,ECC CDH)方案的情况下,双方都具有临时密钥对。见9.2.3.4.6.2。 在One-Pass Diffie-Hellman C(1e,1s,ECC CDH)方案的情况下,只有U方具有临时密钥对。见9.2.3.4.6.3 |
静态密钥 协商密钥对 | 私钥 公钥 | 私钥 公钥 | 在One-Pass Diffie-Hellman C(1e,1s,ECC CDH)方案的情况下,只有V方具有静态密钥对。见9.2.3.4.6.3。 在静态统一模型C(0e,2s,ECC CDH)方案的情况下,U方和V方都具有静态密钥对。见9.2.3.4.6.4。 |
9.2.6.2 Key pair generation
对一组域参数(Q, FR, a, b {,domain_parameter_seed}, G, n, h)生成ECC密钥对d和Q。生成ECC私钥d和公钥Q有两种方法;生成d和Q需要使用这两种方法中的一种。
在生成ECDSA密钥对之前,需要确保域参数(q, FR, a, b{, domain_parameter_seed}, G, n, h)的有效性。
具体操作请参见FIPS PUB 186-4:2013,附录B.4。
9.2.6.3 Public key certificates and infrastructure
9.2.6.3.1 Overview
本子条款9.2.6.3描述了用于DLMS/COSEM的公钥证书,以及管理这些证书的PKI基础设施示例。它基于以下文件:
- NIST SP 800-21:2005和NIST SP 800-32:2001,提供了公钥密码学和公钥基础设施的一般描述;
- ITU-T X.509:2008,规定公钥和属性证书框架;
- RFC 5280,Internet X.509公钥基础设施证书和证书吊销列表(CRL)配置文件;
- NSA3指定了NSA Suite B基本证书和CRL配置文件的。
信任模型如9.2.6.3.2所述。
作为一个例子,PKI体系结构如9.2.6.3.3所述。
9.2.6.4中规定了证书和证书扩展配置文件。
DLMS/COSEM服务器要持有的公钥证书在9.2.6.5中有规定。
9.2.6.6规定了证书的管理。
9.2.6.3.2 Trust model
对于使用公钥密码的基于DLMS/COSEM的电表数据交换系统,应提供各种公私密钥对和公钥证书。
公钥证书将公钥绑定到一个标识:主题。证书由证书颁发机构进行数字签名。
为了提供和管理证书,需要某种形式的公钥基础设施。PKI由颁发证书的证书颁发机构和使用这些证书的终端实体组成。有关PKI示例,请参见9.2.6.3.3。
在最简单的形式中,证书层次结构由一个CA组成。然而,该层次结构通常包含多个具有明确定义的父子关系的CA。还可以部署多个层次结构。
PKI需要一个用于验证证书序列中的第一个证书的信任锚。
信任锚可以是Root-CA证书、Sub-CA证书或直接受信任的密钥
。
注1:信任锚是标记为证书或直接受信任的密钥。但是,此标记不在本技术报告的范围内。
DLMS/COSEM服务器应在制造过程中使用可信带外(OOB)流程配备一个或多个信任锚。
注2:为客户端和第三方提供信任锚不在本技术报告的范围内。
DLMS/COSEM服务器也可以配备有它们自己的证书和CA的证书,DLMS/COSEM客户和第三方。使用受信任的OOB进程或通过"Security setup"对象也可能发生这种情况。
"Security setup"接口类——见DLMS UA 1000-1 Ed.12:2017,4.4.7——提供:
- 提供存储在服务器上的证书信息的属性;
- 一种生成服务器密钥对的方法和一种生成将由客户端发送到CA的服务器上的证书签名请求(CSR)信息的方法;
- 导入、导出和删除证书的方法。
这些属性/方法可以由客户端或第三方通过充当代理的客户端来管理证书。访问"Security setup"对象的属性和方法以及包含的数据的消息应受到适当保护。
证书通常有一个有效期。但是,颁发给DLMS/COSEM服务器的证书可能无限期有效。证书过期后可能会被替换。
在服务器使用证书之前,必须对其进行验证。验证包括:
- 检查证书的语法有效性;
- 检查证书中包含的属性;
- 检查证书有效期是否未过期;
- 检查到信任锚的认证路径;
- 检查证书颁发者的签名。
假设信任锚、其他CA证书以及服务器持有的DLMS/COSEM客户端和第三方的证书都是有效的。系统有责任更换/移除任何有效期已过期或已被吊销的证书。
客户端和第三方还必须在使用服务器证书之前对其进行验证。他们可能有能力验证他们正在使用的证书的状态。但是,这不在本技术报告的范围内。
--------------------SLF NOTE Start--------------------
- DLMS servers 设备制造过程应该预先导入 trust anchors,信任锚、自己的证书、CA 证书、DLMS clients and third parties 证书。
- 设备制造导入证书或信任锚属于 Out of Band (OOB) 带外过程,也就是正规操作以外的过程,正常导入证书应该是通过"Security setup"对象
--------------------SLF NOTE End--------------------
9.2.6.3.3 PKI architecture – informative
9.2.6.3.3.1 General
注1:引言引用自NIST SP 800-21:2005, 3.7。
PKI是一种安全基础设施,用于创建和管理公钥证书,以促进公钥(即非对称密钥)密码学的使用。为了实现这一目标,PKI需要执行两项基本任务:
- 在验证绑定的准确性后,生成并分发公钥证书,以将公钥绑定到其他信息;和
- 维护和分发未过期证书的证书状态信息。

对于DLMS/COSEM,可以预见分层PKI,它包含如下组件,如图75所示。
注2:PKI的实际结构由项目的具体配套规范决定,以满足运营商的需求。
- 根证书颁发机构(Root-CA):见9.2.6.3.3.2;
- 证书颁发机构/下级颁发机构(Sub-CA):见9.2.6.3.3.3;
- 终端实体:不颁发证书的实体:DLMS/COSEM客户端、DLMS/COSEM服务器和第三方:见9.2.6.3.3.4。
9.2.6.3.3.2 Root-CA
Root-CA提供PKI的信任锚。它为Sub-CA颁发证书,并维护证书吊销列表(CRL)。Root-CA证书策略定义了处理证书颁发的规则。
Root-CA拥有根证书C(Root)。Root-CA的证书是使用Root-CA私钥自签名的。Sub-CA证书也使用Root-CA私钥进行签名。
9.2.6.3.3.3 Sub-CA
Sub-CA是为终端实体颁发证书的组织。每个Sub-CA都得到Root-CA的授权。
注:Sub-CA可以是独立的组织,也可以是电表市场参与者、电表运营商、制造商。
每个Sub-CA必须处理一个证书策略,该策略必须符合Root-CA证书策略。
Sub-CA还维护颁发给终端实体的证书列表和证书吊销列表。
Sub-CA拥有证书C(sub CA)。此证书由Root-CA颁发。Sub-CA的私钥用于对终端实体证书进行签名。
9.2.6.3.3.3 End entities
在PKI基础设施中,终端实体是PKI证书的用户和/或作为证书主体的最终用户系统。定义了以下终端实体证书:
- 数字签名密钥证书C(digitalSignature),用于数字签名;
- 静态密钥协商密钥证书C(keyAgreement),用于密钥协商;
- [可选]TLS证书C(TLS),用于在建立TLS安全通道之前在DLMS/COSEM客户端和DLMS/COSEM服务器之间执行身份验证。
另请参见9.2.6.5.
9.2.6.4 Certificate and certificate extension profile
9.2.6.4.1 General
所有证书都应具有为 X.509 V3 证书指定的结构。
对于表示证书和证书扩展名字段的表,适用以下注释:
- m(必填mandatory):必须填写该字段;
- o(可选optional):该字段为可选字段;
- x(不使用do not use):不应使用该字段。
每个证书扩展都被指定为关键或非关键。
如果证书使用系统遇到无法识别的关键扩展或包含无法处理的信息的关键扩展,则必须拒绝证书。
如果未识别非关键扩展,则可以忽略该扩展,但如果已识别,则必须对其进行处理。
本技术报告规定了最低要求。项目特定配套规范可能会规定更严格的要求,例如,本技术报告中指定为可选的字段可能是强制性的,或者指定为非关键的扩展可能指定为关键的。
9.2.6.4.2 The X.509 v3 Certificate
X.509 v3证书是由三个必需字段组成的SEQUENCE,如表23所示
Certificate field | RFC 5280 reference | m/x/o | Value |
---|---|---|---|
Certificate | 4.1.1 | ||
tbsCertificate | 4.1.1.1 | m | See below |
signatureAlgorithm | 4.1.1.2 | m | See below |
signatureValue | 4.1.1.3 | m | See below |
tbsCertificate
字段包含主题
和颁发者的名称
、与主题相关的公钥
、有效期
以及其他相关信息
。tbsCertificate
证书的字段汇总在表24中。tbsCertificate
通常包括扩展;如9.2.6.4.4所述。
signatureAlgorithm
字段包含CA用于对此证书进行签名的加密算法的标识符。
AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER
parameters ANY DEFINED BY algorithm OPTIONAL
}
DLMS/COSEM中使用的两个算法标识符是:
- 在安全套件1的情况下,ecdsa-with-SHA256,OID 1.2.840.10045.4.3.2;
- 在安全套件2的情况下,ecdsa-with-SHA384,OID 1.2.840.10045.4.3.3;
signatureValue
包含根据ASN.1 DER编码的tbsCertificate
计算的数字签名。ASN.1 DER编码的tbsCertificate
用作签名函数的输入。
通过生成此签名,CA验证tbsCertificate
字段中信息的有效性。特别是,CA认证公钥材料
和证书主题
之间的绑定。
9.2.6.4.3 tbsCertificate
9.2.6.4.3.1 Overview
tbcertificate
的字段如表24所示。
Certificate field | RFC 5280 reference | Clause | m/x/o | Comment |
---|---|---|---|---|
tbsCertificate | 4.1.2 | 9.2.6.4.2 | ||
Version | 4.1.2.1 | – | m | ‘v3’ (value is 2) |
Serial Number | 4.1.2.2 | 9.2.6.4.3.2 | m | 由核证机关分配的serial number (不多于20个字节) |
Signature | 4.1.2.3 | – | m | 与证书中的signatureAlgorithm相同的algorithm identifier |
Issuer | 4.1.2.4 | 9.2.6.4.3.3 | m | 证书颁发者的DN (Distinguished name)。 |
Validity | 4.1.2.5 | 9.2.6.4.3.4 | m | 证书的有效性 |
Subject | 4.1.2.6 | 9.2.6.4.3.3 | m | 证书主题的DN (Distinguished name). |
Subject Public Key Info | 4.1.2.7 | 9.2.6.4.3.5 | m | |
Issuer Unique ID | 4.1.2.8 | x | Not applicable | |
Subject Unique ID | 4.1.2.8 | 9.2.6.4.3.6 | o | |
Extensions | 4.1.2.9 | 9.2.6.4.4 | m |
9.2.6.4.3.2 Serial number
根据RFC 5280 4.1.2.2的规定,序列号必须是CA分配给每个证书的正整数。对于给定CA颁发的每个证书,它必须是唯一的(即,颁发者名称和序列号标识唯一的证书)。
证书用户必须能够处理最多20个字节的SerialNumber值。符合条件的CA不得使用超过20个字节的SerialNumber值。
9.2.6.4.3.3 Issuer and Subject
Issuer
字段标识已签署和颁发证书的实体。
Subject
字段标识与存储在Subject公钥字段中的公钥相关联的实体。Subject
可以包含在Subject
字段 和/或subjectAltName
扩展名中。如果主题命名信息仅存在于subjectAltName
扩展中,则主题名称必须是空序列,subjectAltName
扩展必须是关键的。见9.2.6.4.4.6。
PKI各实体的命名方案如下表所示。名称应插入tbsCertificate
的Issuer
或Subject
字段(如果适用的话)。见表25、表26和表27
<>之间的由PKI或者CA分配(如果使用的话)
Attribute | Abbreviation | m/x/o | Name | Comment |
---|---|---|---|---|
Common Name | CN | m | <Root-CA> | Name of Root-CA |
Organization | O | o | <PKI-Name> | Name of PKI |
Organizational Unit | OU | o | Name of organizational unit | |
Country | C | o | ISO 3166 country code | |
<>之间的由PKI或者CA分配(如果使用的话) |
Attribute | Abbrev. | m/x/o | Name | Comment |
Common Name | CN | m | <XXX-CA> | Name of sub-CAThe CN shall finish with "CA" so that the CA function is recognized. |
Organization | O | o | <PKI-Name> | Name of PKI |
Organizational Unit | OU | o | Name of organizational unit | |
Country | C | o | ISO 3166 country code | |
Locality | L | o | <Locality> | Locality where the Sub-CA is located |
State | ST | o | <State> | |
<>之间的由PKI或者CA分配(如果使用的话) |
Root-CA和Sub-CA实例的命名方案元素的格式留给项目特定的配套规范
Attribute | Abbrev. | m/x/o | Name | Comment |
Common Name | CN | m | <System-title> | DLMS/COSEM System title: 8 bytes represented as a 16 characters:Example: "4D4D4D0000BC614E" |
Organization | O | o | <PKI-Name> | Name of PKI |
Organizational Unit | OU | o | Name of organizational unit | |
Country | C | o | ISO 3166 country code | |
Locality | L | x | <Locality> | Locality where the entity is located |
State | S | x | <State> | |
<>之间的由PKI或者CA分配(如果使用的话) |
9.2.6.4.3.4 Validity period
证书有效期是CA保证维护证书状态信息的时间间隔。该字段表示为两个日期的SEQUENCE:
- 证书有效期开始的日期(notBefore);和
- 证书有效期结束的日期(notAfter)。
在CA证书的情况下,Sub-CA证书和DLMS/COSEM服务器以外的终端实体notBefore和notAfter应为明确的日期。
DLMS/COSEM服务器可以获得证书,但不能为其指定良好的到期日期;这样的证书旨在用于设备的整个寿命。
如果没有明确的结束日期(notAfter),可以为notAfter分配GeneralizedTime值99991231235959Z
9.2.6.4.3.5 SubjectPublicKeyInfo
SubjectPublicKeyInfo
应该是下面的结构
SubjectPublicKeyInfo ::= SEQUENCE
{
Algorithm AlgorithmIdentifier,
subjectPublicKey BIT STRING
}
AlgorithmIdentifier应该是ASN.1结构
AlgorithmIdentifier ::= SEQUENCE
{
algorithm OBJECT IDENTIFIER,
parameters ANY DEFINED BY algorithm OPTIONAL
}
AlgorithmIdentifier
用于识别加密算法。OBJECT IDENTIFIER
组件标识算法(例如带有SHA-1的DSA)。可选参数字段的内容将根据所识别的算法而变化。此字段必须包含与序列tbsCertificate
中的签名字段相同的算法标识符;见9.2.6.4.2
算法OBJECT IDENTIFIER
应包含值
- OID值:1.2.840.10045.2.1;
- OID描述:ECDSA和ECDH公钥
对于曲线NIST P-256,parameters
值应为1.2.840.10045.3.1.7,对于曲线NIST P-384,parameters
值为1.3.132.0.34。
SubjectPublicKeyInfo
中的subjectPublicKey
是ECC公钥。ECC公钥具有以下语法:
ECPoint::= OCTET STRING
根据本技术报告,椭圆曲线密码的实现必须支持ECC公钥的未压缩形式,并且可能支持压缩形式。不得使用
[X9.62]中ECC公钥的混合形式。
按照SEC1:2009的规定:
- 椭圆曲线公钥(ECPoint类型的值,即OCTET STRING)映射到
subjectPublicKey
(BIT STRING类型的值),如下所示:OCTET STRING值的最高有效位变为BIT STRIN值的最有效位,依此类推;OCTET STRING的最低有效位变为位字符串的最小有效位。转换例程见SEC1:2009第2.3.1节和第2.3.2节; - OCTET STRING的第一个八位字节表示密钥是压缩的还是未压缩的。未压缩的形式用0x04表示,压缩的形式由0x02或0x03表示(参见SEC1:2009中的2.3.3),如果第一个八位字节中包含任何其他值,则必须拒绝公钥。
9.2.6.4.3.6 Subject Unique ID
除了服务器证书之外,在终端设备证书中可以选择性地使用Subject Unique ID
。
该字段的使用留给项目特定的配套规范。
9.2.6.4.4 Certificate extensions
9.2.6.4.4.1 Overview
为X.509 v3证书定义的扩展提供了将附加属性与用户或公钥关联以及管理CA之间关系的方法。证书中的每个扩展都被指定为关键(TRUE)或非关键(FALSE)。
扩展字段必须根据所使用的证书类型完成,如表28所示。
Attributes | RFC 5280reference | Clause | CAs | End entities | ||||
---|---|---|---|---|---|---|---|---|
C(Root) | C(Sub- CA) | C(TLS) | C(Key Agree) | C(Data Sign) | ||||
1 | AuthorityKeyIdentifier | 4.2.1.1 | 9.2.6.4.4.2 | o | m | m | m | m |
2 | SubjectkeyIdentifier | 4.2.1.2 | 9.2.6.4.4.3 | m | m | o | o | o |
3 | KeyUsage | 4.2.1.3 | 9.2.6.4.4.4 | m | m | m | m | m |
4 | CertificatePolicies | 4.2.1.4 | 9.2.6.4.4.5 | o | m | m | o | o |
5 | SubjectAltNames | 4.2.1.6 | 9.2.6.4.4.6 | o | o | o | o | o |
6 | IssuerAltNames | 4.2.1.7 | 9.2.6.4.4.7 | o | o | x | x | x |
7 | BasicConstraints | 4.2.1.9 | 9.2.6.4.4.8 | m | m | x | x | x |
8 | ExtendedKeyUsage | 4.2.1.12 | 9.2.6.4.4.9 | x | x | m | x | x |
9 | cRLDistributionPoints | 4.2.1.13 | 9.2.6.4.4.10 | o | o | x | x | x |
C(Root): Root-CA的证书 C(Sub-CA): Sub-CA的证书 C(TLS): 传输层安全证书 C(KeyAgree): 证书一个ECDH能力的密钥建立密钥 C(DataSign): 支持ECDSA的签名密钥的证书 |
9.2.6.4.4.2 Authority Key Identifier
- 扩展ID(OID):2.5.29.35;
- 关键:否;
- 说明:AuthorityKeyIdentifier扩展提供了一种识别与用于签署证书的私钥相对应的公钥的方法;
- 值:AuthorityKeyIdentifier扩展必须包括
keyIdentifier
字段。
keyIdentifier
字段的值需要计算为:
- 使用RFC 5280,4.2.1.2中定义的方法1,即
keyIdentifier
由Bit STRING SubjectPublicKey值的160位SHA-1哈希组成(不包括标签、长度和未使用位的数量);或 - 使用RFC 5280,4.2.1.2中定义的方法2,即
keyIdentifier
由一个四位类型字段组成,该字段的值为0100,后跟Bit STRINGsubjectPublicKey
值的SHA-1哈希的最低有效60位(不包括标签、长度和未使用位的数量)。
注:方法的选择由项目特定配套规范决定。
9.2.6.4.4.3 SubjectKeyIdentifier
- 扩展ID(OID):2.5.29.14;
- 关键:否;
- 说明:
SubjectKeyIdentifier
扩展提供了一种识别包含特定公钥的证书的方法; - 值:
SubjectKeyIdentifier
扩展必须包括keyIdentifier字段。
有关keyIdentifier的计算方法,请参见9.2.6.4.4.2。
9.2.6.4.4.4 KeyUsage
- 扩展ID(OID):2.5.29.15;
- 关键:是;
- 说明:
KeyUsage
扩展定义了证书中包含的密钥的用途; - 值:应设置的位如表29所示。
Certificate | C(Root) | C(Sub-CA) | C(TLS) | C(KeyAgree) | C(DataSign) |
---|---|---|---|---|---|
Bits to be set | keyCertSign, cRLSign | keyCertSign, cRLSign | digitalSignature keyAgreement | keyAgreement | digitalSignature |
有关详细信息,请参阅RFC 5280、4.2.1.3和NSA3。
9.2.6.4.4.5 CertificatePolicies
扩展ID(OID):2.5.29.32;
- 关键:否;
- 描述:证书策略扩展包含一个或多个策略信息项的序列,每个策略信息项由对象标识符(OID)和可选限定符组成。有关详细信息,请参阅RFC 5280,4.2.1.4;
- 值:包含适用证书策略的OID。
9.2.6.4.4.6 SubjectAltNames
- 扩展ID(OID):2.5.29.17;
- 关键:如果证书的
subject
字段为空(空序列),则为是,否则为否。
说明:此扩展允许将身份绑定到证书的主题。这些身份可以作为证书主题字段中身份的补充或替代。如果受试者名称为空序列,则subjectAltName扩展名必须添加到终端实体签名和密钥建立证书中,并且必须标记为关键。subjectAltName
扩展名是可选的,否则,如果包含,则必须标记为关键。
SubjectAltName
扩展在使用时应包含OtherName类型的单个GeneralName,该GeneralName被进一步细分为IETF RFC 4108中定义的硬件模块名称(硬件模块名称上的id)。hwSerialNum字段应设置为系统标题。 - 值:查看表30所示。
Certificate | C(Root) | C(Sub-CA) | C(TLS) | C(KeyAgree) | C(DataSign) |
---|---|---|---|---|---|
rfc822Name | <E-Mail Address> | <E-Mail Address> | - | – | – |
uRI | <Web site> | <Web site> | - | – | – |
otherName | - | - | - | <otherName> | <otherName> |
<>之间的由PKI或者CA分配(如果使用的话) |
9.2.6.4.4.7 IssuerAltName
- 扩展ID(OID):2.5.29.18;
- 关键:否;
- 说明:此扩展用于将Internet样式标识与证书颁发者相关联。
有关详细信息,请参阅RFC 5280,4.2.1.7; - 数值:见表31。
Certificate | C(Root) | C(Sub-CA) | C(TLS) | C(KeyAgree) | C(dataSign) |
---|---|---|---|---|---|
rfc822Name | <E-Mail Address> | <E-Mail Address> | – | – | – |
URI | <Web site> | <Web site> | – | – | – |
<>之间的由PKI或者CA分配(如果使用的话) |
9.2.6.4.4.8 Basic constraints
- 扩展ID(OID):2.5.29.19;
- 关键:是;
- 描述:基本约束扩展确定证书的主体是否是CA,以及包括该证书的有效证书路径的最大长度。参见RFC 5280,4.2.1.9;
深度指在证书链中,从终端实体证书到根证书的最大证书数量,限制2级CA的深度
- 数值:见表32。
Certificate | C(Root) | C(Sub-CA) | C(TLS) | C(KeyAgree) | C(dataSign) |
---|---|---|---|---|---|
CA | TRUE | TRUE | – | – | – |
pathLenConstraint | See Note 1 | See Note 1 | – | – | – |
<>之间的由PKI或者CA分配(如果使用的话) |
9.2.6.4.4.9 Extended Key Usage
- 扩展ID(OID):2.5.29.37;
- 关键:否;
- 说明:表示证书可以用作TLS服务器证书;
- TLS服务器身份验证OID:1.3.6.1.5.5.7.3.1;
- TLS客户端身份验证OID:1.3.6.1.5.5.7.3.2。
9.2.6.4.4.10 cRLDistributionPoints
- 扩展ID(OID):2.5.29.31;
- 关键:否;
- 描述:CRL分发点扩展标识CRL信息的获取方式;
- DLMS/COSEM服务器证书中未使用此扩展。
9.2.6.4.4.11 Other extensions
本配置文件中未描述的所有其他扩展都应视为可选;它们的包含或排除及其值将取决于特定的应用程序或PKI配置文件。
9.2.6.5 Other extensions
每个DLMS/COSEM服务器都必须使用X.509 v3格式,并包含以下内容之一:
- 具有P-256或P-384 ECDSA功能的签名密钥;或
- 具有P-256或P-384 ECDH功能的密钥协商密钥。
每个证书都必须使用ECDSA进行签名。如果证书包含P-256上的密钥,则签名CA的密钥必须是P-256或P-384。如果证书包含P-384上的密钥,则签名CA的密钥必须是P-384。
根据安全策略,以下X.509 v3证书应由DLMS/COSEM终端实体处理,见表33:
Security suite 1 | Security suite 2 | Role |
---|---|---|
根证书颁发机构(Root-CA),使用P-256签名的自签名证书 | 根证书颁发机构(Root-CA),使用P-384签名的自签名证书 | 信任锚;可能不止一个。 |
从属CA(Sub-CA)使用P-256签名的证书 | 从属CA(Sub-CA)使用P-384签名的证书 | 颁发CA的证书。Sub-CA也可以用作信任锚。 |
– | 用P-384签名P-256的从属CA证书(Sub-CA) | |
使用P-256签名的终端实体签名证书 | 使用P-384签名的终端实体签名证书 | 生成和验证ECDSA签名的公钥 |
– | 用P-384签名P-256的终端实体签名证书 | |
使用P-256签名的终端实体密钥建立证书 | 使用P-384签名的终端实体密钥建立证书 | 与One-Pass Diffie-Hellman C(1e, 1s)方案或与静态统一模型C(0e, 2s, ECC CDH)方案配合使用 |
– | 用P-384签名P-256的终端实体签名证书 | |
使用P-256签名的终端实体TLS证书 | 使用P-384签名的终端实体TLS证书 | |
– | 用P-384签名P-256的终端实体TLS证书 |
附件B中给出了证书示例。
--------------------SLF NOTE Start--------------------
Root-CA 自签名证书(信任锚),Sub-CA 证书用于 ECDSA 签名生成和验签的证书
--------------------SLF NOTE End--------------------
9.2.6.6 Management of certificates
9.2.6.6.1 Overview
第9.2.6.6款仅适用于DLMS/COSEM服务器中公钥证书的管理,包括:
- 为服务器提供信任锚,请参见9.2.6.6.2;
- 为服务器提供更多CA证书,请参见9.2.6.6.3;
- 服务器的安全个性化,见9.2.6.6.4;
- 为服务器提供客户端和第三方的证书,见9.2.6.6.5;
- 为客户端和第三方提供服务器证书,见9.2.6.6.6;
- 移除证书,见9.2.6.6.7。
注:DLMS/COSEM客户端和第三方系统中公钥证书的管理不在本技术报告的范围内。
9.2.6.6.2 Provisioning servers with trust anchors
在开始稳定状态操作之前,应该为服务器提供将用于验证证书的信任锚。信任锚可以是Root-CA(即自签名)证书、Sub-CA证书或直接受信任的CA密钥。一个服务器可以配置多个信任锚。
信任锚应放置在带外(OOB)服务器中。
信任锚证书与其他证书一起存储。
它们可以被导出,但不能被导入或删除
直接信任的CA公钥不能导出
--------------------SLF NOTE Start--------------------
- 这个是否有安全问题,比如 windows 有专门的受信任根证书区域,每个分类都有专属区域。
- 解释了上面的安全问题,是有防篡改保护的
--------------------SLF NOTE End--------------------
9.2.6.6.3 Provisioning the server with further CA certificates
服务器可以配置更多的CA(应该是 Sub-CA,非信任锚)证书,这些证书将用于验证终端设备证书上的数字签名。可以使用"Security setup"对象的import_certificate方法。流程如图76所示。

当第三方负责管理CA证书时,该第三方可以通过充当代理的客户端调用import_certificate方法。
9.2.6.6.4 Security personalisation of the server
安全个性化意味着为服务器提供非对称密钥对和相应的公钥证书。这可以发生:
- 使用制造商提供的安全原语注入私钥和公钥证书。私钥必须安全地存储在服务器中,永远不能暴露;或
- 使用"Security setup"对象的适当方法。这个过程可以在制造过程中使用,也可以在需要生成新的密钥对和相关的公钥证书时使用。此过程如图77所示,并在下面进行描述

安全个性化可以由第三方而不是客户端执行。在这种情况下,第三方可以通过充当代理的客户端调用"Security setup"对象的方法安全个性化导入非对称密钥
:
通过设备商专有方式导入私钥和公钥证书"Security setup"相关函数产生
- 客户端调用
generate_key_pair
方法。方法调用参数指定要生成的特定用途的密钥对:数字签名、密钥协商或 TLS; - 客户端调用
generate_certificate_request
方法。方法调用参数标识生成证书签名请求(CSR)所需的密钥对。返回参数包括CSR,由新生成的密钥对的私钥签名; - 客户端向CA发送CSR,该消息封装了调用
generate_certificate_request
方法得到的返回参数。CA(如果满足必要条件) 颁发证书并将其发送给客户端; - 客户端调用
import_certificate
方法。方法调用参数包含证书。服务器验证证书,如果成功,则将证书上的信息添加到certificates属性。如果验证失败,证书将被丢弃。
可能只有一个密钥对和证书用于相同的目的(数字签名、密钥协商、TLS)。因此,当新证书导入成功后,旧证书将被移除
。从这里开始,新的密钥对可以用于事务。
使用服务器证书的各方可以通过以下方式获得证书 :
- out of band ;
- 使用"Security setup"对象的
export_certificate
方法,见9.2.6.6.6 - 作为AARE的一部分(在HLS认证期间),见9.2.7.4
9.2.6.6.5 Provisioning servers with certificates of clients and third parties
为了验证数字签名,为了使用静态的密钥协商的密钥
的方案执行密钥协商,或者为了建立TLS连接,服务器需要拥有对方的适当的公钥证书。
如果在制造时已经知道客户端和/或第三方,则制造商可以将其公钥证书注入服务器。
向制造商分发公钥证书不在本技术报告的范围内。
否则,可以使用"Security setup"对象的import_certificate
方法向服务器提供客户端和第三方的证书。方法调用参数是要放置在服务器中的证书。具体的方法调用和返回参数请参见DLMS UA 1000-1 Ed. 12.2: 2017,4.4.7。流程如图78所示。

第三方也可以使用客户机作为代理调用import_certificate (data)方法。
在使用ECDSA的HLS认证机制中,客户端数字签名密钥的公钥证书可以由AARQ的calling-AE-qualifier
字段携带。详情查看9.2.7.4。
9.2.6.6.6 Provisioning clients and third parties with certificates of servers
要验证服务器应用的数字签名,执行涉及静态的密钥协商的密钥
的密钥协商,或建立TLS连接,客户端或第三方需要拥有服务器的适当公钥证书。
证书可以与服务器一起交付,并插入到客户端/第三方OOB中。
或者,客户端或第三方可以使用"Security setup"对象的export_certificate
方法从服务器请求证书。方法调用参数标识所请求的证书。
对于使用ECDSA的HLS认证(即authentication_mechanism 7),用于数字签名的服务器公钥证书在AARE中传输。
在成功的情况下,返回参数包括证书。具体的方法调用和返回参数请参见DLMS UA 1000-1 Ed. 12.2: 2017,4.4.7。流程如图79所示。
export_certificate (data)方法也可以由第三方调用,使用客户机作为代理
9.2.6.6.7 Certificate removal from the server
有时需要删除服务器存储的公钥证书。
注1:这可能涉及到属于服务器的证书或属于客户端或第三方的证书。
注2:需要移除公钥证书的情况不在本技术报告的范围之内。
当属于服务器的证书被删除时,与公钥关联的私钥将被销毁。
删除的证书信息也应从"Security setup"对象的证书属性中删除。
Security setup "对象的 remove_certificate 方法用于删除证书
公钥证书已被删除的密钥对不能再用于事务。流程如图80所示。

remove_certificate (data)方法也可以由第三方调用,使用客户机作为代理
9.2.7 Applying cryptographic protection
9.2.7.1 Overview
9.2.3中规定的加密算法可以应用:
- 保护xDLMS apdu,见9.2.7.2;
- 处理HLS认证过程中的交换,见9.2.7.4;
- 保护COSEM数据,见9.2.7.5。
9.2.7.2 Protecting xDLMS APDUs
9.2.7.2.1 Overview
本小节9.2.7.2规定了9.2.3.3和9.2.3.4中规定的加密算法
可用于保护xDLMS apdu:
- 9.2.7.2.2指定安全策略和访问权限的可能值;
- 9.2.7.2.3给出了加密apdu的类型;
- 9.2.7.2.4指定使用AES-GCM算法进行认证和加密;
- 9.2.7.2.5指定使用ECDSA算法进行数字签名。
当AP调用COSEM对象属性或与方法相关的xDLMS服务原语时,服务参数包括Security_Options
参数。该参数告知AL要使用的加密APDU的类型,要应用的保护,并包括必要的安全材料。AL首先构建与服务原语相对应的APDU,然后构建加密后的APDU。
当AL从远程伙伴接收到加密后的APDU时,它将对其进行解码并恢复原始的、未加密的APDU。成功完成后,它调用适当的服务原语。附加的服务参数包括Security_Status
和Protection_Element
参数,它们通知AP所使用的加密APDU的类型、已验证和删除的保护,还可能包括安全材料。见9.3.5。
9.2.7.2.2 Security policy and access rights values
在Security setup 版本 1
的情况下(参见DLMS UA 1000-1 Ed. 12.2: 2017,4.4.7),枚举类型应被解释为unsigned 8类型;每一位的含义如表34所示。
Bit | Security policy |
---|---|
0 | unused, shall be set to 0 |
1 | unused, shall be set to 0 |
2 | authenticated request |
3 | encrypted request |
4 | digitally signed request |
5 | authenticated response |
6 | encrypted response |
7 | digitally signed response |
以"安全策略"版本0为例,可能的安全策略值在DLMS UA 1000-1 Ed. 12.2: 2017,5.4.10中指定。对于"安全策略"版本0和1,值(0)表示不需要加密保护。 |
访问权限由"Association LN"的object_list属性或"Association SN"对象的access_rights_list持有。access_rights中的access_mode元素决定了访问类型,并规定了加密保护。它是一个枚举数据类型。
对于Association LN version 3 and Association SN version 4
请参见DLMS UA 1000-1 ed .12.2: 2017,4.4.4。在4.4.3中,枚举值被解释为unsigned8,每个位的含义如表35所示。
对于旧版本,请参阅DLMS UA 1000-1中的规范,即"蓝皮书"。
Bit | Attribute access | Method access |
---|---|---|
0 | read-access | access |
1 | write-access | not-used |
2 | authenticated request | authenticated request |
3 | encrypted request | encrypted request |
4 | digitally signed request | digitally signed request |
5 | authenticated response | authenticated response |
6 | encrypted response | encrypted response |
7 | digitally signed response | digitally signed response |
Examples | enum (3): read-write enum (6) write access with authenticated request enum (255): read-write access withauthenticated, encrypted and digitally signed request and response | enum (1): access enum (2): not used enum(5): access with authenticated request enum (253): access with authenticated,encrypted and digitally signed request and response |
对COSEM对象属性和/或方法的访问权限可能需要经过身份验证、加密和/或签名的xDLMS apdu。出于这个原因,总是允许apdu提供比安全策略所需更多的保护。不符合安全策略和访问权限要求的apdu应被拒绝。
在此上下文中,更多的保护意味着在xDLMS APDU上应用的保护种类比安全策略所要求的要多:例如,安全策略要求所有APDU都经过身份验证,但访问权限要求对APDU进行加密和身份验证,即更高的保护。
9.2.7.2.3 Ciphered xDLMS APDUs
不同类型的加密xDLMS apdu如表36所示。参见9.3.5
加密的xDLMS apdu只能在加密的应用程序上下文中使用。另一方面,在加密的应用程序上下文中,可以同时使用加密和未加密的apdu。
就是说 应用程序上下文=加密的xDLMS apdu+未加密的xDLMS apdu
APDU type | Parties | Type of ciphering | Security services | Key used | Compression |
---|---|---|---|---|---|
Service-specific glo-ciphering or ded-ciphering | Client – Server | 对称密钥 | Authentication Encryption | 分组加密密钥:
| – |
general-glo-ciphering general-ded-ciphering | Yes5 | ||||
general- ciphering | Third party or Client – Server | 对称密钥 | Authentication Encryption | 分组加密密钥:
| Yes5 |
general-signing | 非对称密钥 | Digital signature | Signing key | No | |
(1)由AARQ传输; (2)密钥建立可以是密钥封装或密钥协商; (3)在服务器端,这些密钥由Security setup对象持有; (4)关键数据在受保护的APDU中传输; (5)压缩的使用由Security Control字节控制。 |
--------------------SLF NOTE Start--------------------
general-ded-ciphering dedicated 专用的,使用专用密钥, AARQ时协商
general-glo-ciphering global 全局的,使用全局密钥,比如 GUEK
--------------------SLF NOTE End--------------------
9.2.7.2.4 Encryption, authentication and compression
9.2.7.2.4.1 Overview
使用AES-GCM算法保护信息的加密和身份验证如图81所示。参见9.2.3.3.7。该算法可以与压缩相结合。
在消息保护的情况下,要保护的信息是xDLMS APDU。
在COSEM数据保护的情况下,需要保护的信息是COSEM数据,即COSEM属性值或方法调用/返回参数。

所需的安全材料在9.2.7.2.4.2 - 9.2.7.2.4.5中规定。
9.2.7.2.4.2 The security header
bit 7 | bit 6 | bit 5 | bit 4 | bits 3-0 |
Compression 是否压缩 | Key_Set 0:单播 1:广播 service-specific dedicated ciphering, the general-ded-ciphering , the general-ciphering APDUs 时候始终为0 | E 是否加密 | A 是否认证 | Security_Suite_Id 见Security_Suite |
9.2.7.2.4.3 Plaintext and Additional Authenticated Data
P:明文,表示
A:附加认证数据,这取决于保护的类型。它们如表38所示,其中SC是安全控制字节,
AK:身份验证密钥,
I:信息,即要保护的xDLMS APDU或COSEM数据,。
Security control,SC | Protection | P | A, Additional Authenticated Data | ||
---|---|---|---|---|---|
E field | A field | Service-specific glo-ciphering Service-specific ded-ciphering general-glo-ciphering general-ded-ciphering | general-ciphering | ||
0 | 0 | None | – | – | – |
0 | 1 | Authenticated only | – | SC || AK || (C) I | SC || AK || transaction-id || 1 originator-system-title || 1 recipient-system-title || 1 date-time1 || other-information || 1 (C) I |
1 | 0 | Encrypted only | (C) I | – | – |
1 | 1 | Encrypted and authenticated | (C) I | SC || AK | SC || AK || transaction-id || 1 originator-system-title || 1 recipient-system-title || 1 date-time|| 1 other-information 1 |
1) 字段transaction id...other-information 是A-XDR编码的OCTET STRINGs。每个字段的长度和值都包含在AAD中。 |
9.2.7.2.4.4 Encryption key and authentication key
AES-GCM使用的这些密钥分别在9.2.3.3.7.4和9.2.3.3.7.5中指定。在9.2.5中指定了DLMS/COSEM中使用的各种密钥及他们的建立。
9.2.7.2.4.5 Initialization vector
见 9.2.3.3.7.3
9.2.7.2.4.6 Service-specific ciphering xDLMS APDUs
对于某些xDLMS apdu(请参阅9.1.4.4.6和9.5),可以使用使用全局密钥的加密变体和使用专用密钥的加密变体。这些经过加密的apdu可以在客户机和服务器之间使用。特定于服务的加密(service-specific ciphering)apdu
的结构如图82所示。参见表38和表39。

9.2.7.2.4.7 The general-glo-ciphering and general-ded-ciphering xDLMS APDUs
这些apdu可用于使用全局密钥或专用密钥对其他xDLMS apdu进行加密。它们可以在客户机和服务器之间使用。它们的结构如图83所示。参见表38和表39。

9.2.7.2.4.8 The general-ciphering APDU
general-ciphering APDU可以在客户机和服务器之间或第三方和服务器之间使用。这些apdu还携带有关要使用的密钥的必要信息。general-ciphering APDU
的结构如图84所示。参见表38和表39。

9.2.7.2.4.9 Use of the fields of the ciphering xDLMS APDUs
表39总结了加密xDLMS apdu字段的使用情况
APDU field | Service-specific global / dedicated ciphering | general-glo-/general-ded-ciphering | general-ciphering | Meaning |
---|---|---|---|---|
tag | Service specific | [219] [220] | [221] | [219] [220] |
system-title | - | + | - | See 9.3.5 |
transaction-id | - | + | - | |
originator-system-title | - | - | + | |
recipient-system-title | - | - | + | |
date-time | - | - | + | |
other-information | - | - | + | |
key-info | - | - | + | |
security control byte | + | + | + | 提供有关应用的保护、密钥集和使用的安全套件的信息。见表37,在general-ciphering APDU的情况下,安全控制字节的密钥集位是不相关的,应该设置为零。 |
Invocation counter | - | - | + | 初始化向量的调用字段。它是一个整数计数器,每次使用相同的密钥调用经过身份验证的加密函数时递增。当建立新密钥时,相关的调用计数器应重置为0。 |
unprotected APDU | + | + | + | 未受保护的APDU(与要保护的APDU相同)。 |
encrypted APDU | + | + | + | 加密的APDU,即密文。 |
unprotected APDU | + | + | + | 由AES-GCM算法计算,参见9.2.3.3.7。 |
9.2.7.2.4.10 Encoding example: global-get-request xDLMS APDU
表40显示了特定于服务的全局加密xDLMS APDU的编码示例:glo-get-request
X | Contents | LEN(X)bytes | Len(X)bits | |||
---|---|---|---|---|---|---|
Security material | ||||||
Security suite | GCM-AES-128 | |||||
System Title | Sys-T | 4D4D4D0000BC614E(在这里,最后五个字节包含十六进制的制造编号) | 8 | 64 | ||
Invocation counter | IC | 01234567 | 4 | 32 | ||
Initialization Vector | IV | Sys-T || IC | 12 | 96 | ||
4D4D4D0000BC614E01234567 | ||||||
Block cipher key(global) | EK | 000102030405060708090A0B0C0D0E0F | 16 | 128 | ||
Authentication Key | AK | D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF | 16 | 128 | ||
Security applied | Authentication | Encryption | Authenticated encryption | |||
Security controlbyte (with unicast key) | SC | SC-A | SC-E | SC-AE | 1 | 8 |
10 | 20 | 30 | ||||
Security header | SH | SH = SC-A || IC | SH = SC-E || IC | SH = SC-AE || IC | ||
1001234567 | 2001234567 | 3001234567 | 5 | 40 | ||
Inputs | Authentication | Encryption | Authenticated encryption | |||
xDLMS APDU tobe protected | APDU | C0010000080000010000FF0200(Get-request, attribute 2 of the Clock object) | 13 | 104 | ||
Plaintext | P | Null | C0010000080000010000FF0200 | C0010000080000010000FF0200 | 13 | 104 |
Associated data | A | SC||AK||APDU | – | SC||AK | ||
Associated Data – Authentication | A-A | 10D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFC0010000080000010000FF0200 | – | – | 30 | 240 |
Associated Data – Encryption | A-E | – | – | – | 0 | 0 |
Associated Data –Authenticated encryption | A-AE | – | – | 30D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF | 17 | 136 |
Outputs | Authentication | Encryption | Authenticated encryption | |||
Ciphertext | C | NULL | 411312FF935A47566827C467BC | 411312FF935A47566827C467BC | 13 | 104 |
Authentication tag | T | 06725D910F9221D263877516 | – | 7D825C3BE4A77C3FCC056B6B | 12 | 96 |
The complete Ciphered APDU | TAG||LEN||SH||APDU||T | TAG||LEN||SH||C | TAG||LEN||SH||C||T | – | – | |
Authenticated APDU | C8(glo-get-request) 1E(长度) 10(SH) 01234567(IC) C0010000080000010000FF0200(明文P) 06725D910F9221D263877516(Authentication tag) | – | – | 32 | 256 | |
Encrypted APDU | – | C8(glo-get-request) 12(长度) 20(SH) 01234567(IC) 411312FF935A47566827C467BC(密文C) | – | 20 | 160 | |
Authenticated and encrypted APDU | – | – | C8(glo-get-request) 1E(长度) 30(SH) 01234567 411312FF935A47566827C467BC(密文C) 7D825C3BE4A77C3FCC056B6B(Authentication tag) | 32 | 256 | |
本例中调用计数器的值为01234567。在实际生活中,每次调用AES-GCM算法时,该值都会增加。AES加密之后,密文长度不变,因此明文P长度是13,密文C长度还是13 |
表41显示了一个示例,其中ACCESS。请求和访问。表134中所示的响应apdu使用经过身份验证的加密进行保护。使用9.2.7.2.4.8中指定的通用加密APDU。加密密钥采用One-Pass Diffie-Hellman C(1e, 1s,ECC CDH)密钥协商方案,参见9.2.3.4.6.3。验证密钥与表40中相同。
Message Elements | Contents | LEN (Bytes) |
---|---|---|
General-Ciphering | DD | 1 |
transaction-id | 0 | |
length | 08 | 1 |
value | 0102030405060708 | 8 |
originator-system-title | 0 | |
length | 08 | 1 |
value | 4D4D4D0000BC614E | 8 |
recipient-system-title | 0 | |
length | 08 | 1 |
value | 4D4D4D0000000001 | 8 |
date-time | 0 | |
length | 00 | 1 |
value | 0 | |
other-information | 0 | |
length | 00 | 1 |
value | 0 | |
key-info OPTIONAL | 01 | 1 |
agreed-key CHOICE | 02 | 1 |
key-parameters | 0 | |
length | 01 | 1 |
value | 01 | 1 |
key-ciphered-data | 0 | |
length | 8180 | 2 |
value | C323C2BD45711DE4688637D919F92E9DB8FB2DFC213A88D21C9DC8DCBA917D8170511DE1BADB360D50058F794B0960AE11FA28D392CFF907A62D13E3357B1DC0B51BE089D0B682863B2217201E73A1A9031968A9B4121DCBC3281A69739AF87429F5B3AC5471E7B6A04A2C0F2F8A25FD772A317DF97FC5463FEAC248EB8AB8BE | 128 |
ciphered-content | 0 | |
length | 81EB | 2 |
value | 3100000000F435069679270C5BF4425EE5777402A6C8D51C620EED52DBB188378B836E2857D5C053E6DDF27FA87409AEF502CD9618AE47017C010224FD109CC0BEB21E742D44AB40CD11908743EC90EC8C40E221D517F72228E1A26E827F43DC18ED27B5F458D66508B05A2A4CC6FED178C881AFC3BC67064689BE8BB41C80ABB3C114A31F4CB03B8B64C7E0B4CE77B2399C93347858888F92239713B38DF01C4858245827A92EF334172EA636B31CBBDF2A96AD5D035F66AA38F1A2D97D4BBA99622E6B5F18789CECB2DFB3937D9F3E17F8B472098E6563238F37528374809836002AEA6E7012D2ADFAA7 | 235 |
general-ciphering(encoded) | DD080102030405060708084D4D4D0000BC614E084D4D4D00000000010000010201018180C323C2BD45711DE4688637D919F92E9DB8FB2DFC213A88D21C9DC8DCBA917D8170511DE1BADB360D50058F794B0960AE11FA28D392CFF907A62D13E3357B1DC0B51BE089D0B682863B2217201E73A1A9031968A9B4121DCBC3281A69739AF87429F5B3AC5471E7B6A04A2C0F2F8A25FD772A317DF97FC5463FEAC248EB8AB8BE81EB3100000000F435069679270C5BF4425EE5777402A6C8D51C620EED52DBB188378B836E2857D5C053E6DDF27FA87409AEF502CD9618AE47017C010224FD109CC0BEB21E742D44AB40CD11908743EC90EC8C40E221D517F72228E1A26E827F43DC18ED27B5F458D66508B05A2A4CC6FED178C881AFC3BC67064689BE8BB41C80ABB3C114A31F4CB03B8B64C7E0B4CE77B2399C93347858888F92239713B38DF01C4858245827A92EF334172EA636B31CBBDF2A96AD5D035F66AA38F1A2D97D4BBA99622E6B5F18789CECB2DFB3937D9F3E17F8B472098E6563238F37528374809836002AEA6E7012D2ADFAA7 | 401 |
General-Ciphering | DD | 1 |
transaction-id | 0 | |
length | 08 | 1 |
value | 0123456789012345 | 8 |
originator-system-title | 0 | |
length | 08 | 1 |
value | 4D4D4D0000000001 | 8 |
recipient-system-title | 0 | |
length | 08 | 1 |
value | 4D4D4D0000BC614E | 8 |
date-time OPTIONAL | 0 | |
length | 00 | 1 |
value | 0 | |
other-information | 0 | |
length | 00 | 1 |
value | 0 | |
key-info OPTIONAL | 01 | 1 |
agreed-key CHOICE | 02 | 1 |
key-parameters | 0 | |
length | 01 | 1 |
value | 01 | 1 |
key-ciphered-data | 0 | |
length | 8180 | 2 |
value | 6439724714B47CD9CB988897D8424AB946DCD083D37A954637616011B9C2378773295F0F850D8DAFD1BBE9FE666E53E4F097CD10B38B69622152724A90987444E1FF47974A1F6931A6502F58147463F0E8CC517D47F55B0AC56DD8AC5C9D0E481934F2D90F9893016BD82B6E3FFE21FF1588F3278B4E9D98EB4FB62ADD64B380 | 128 |
ciphered-content | 0 | |
length | 3D | 1 |
value | 3100000000B3FFCAA594642D8319CEC6B2A233E2BF4621D6991B97E4565B986E8CCBE9A299D8E7869723638FF6BB20E66E175E6F2D762CFD26B3D58733 | 61 |
general-ciphering (encoded) | 3100000000F435069679270C5BF4425EE5777402A6C8D51C620EED52DBB188378B836E2857D5C053E6DDF27FA87409AEF502CD9618AE47017C010224FD109CC0BEB21E742D44AB40CD11908743EC90EC8C40E221D517F72228E1A26E827F43DC18ED27B5F458D66508B05A2A4CC6FED178C881AFC3BC67064689BE8BB41C80ABB3C114A31F4CB03B8B64C7E0B4CE77B2399C93347858888F92239713B38DF01C4858245827A92EF334172EA636B31CBBDF2A96AD5D035F66AA38F1A2D97D4BBA99622E6B5F18789CECB2DFB3937D9F3E17F8B472098E6563238F37528374809836002AEA6E7012D2ADFAA7 | 226 |
9.2.7.2.5 Digital signature
该算法为9.2.3.4.5中规定的椭圆曲线数字签名算法(ECDSA)。
general-signingAPDU的结构如图85所示。其他字段请参见表39和9.3.5。

9.2.7.3 Multi-layer protection by multiple parties
加密保护可以由多方应用。一般而言,当事人是:
- 服务器;
- 客户;
- 第三方。
每一方都可以使用一层或多层保护:
- 要应用加密、身份验证或经过身份验证的加密,则使用加密apdu。第三方应使用general-cipheringAPDU。客户端可以使用任何加密apdu。经过身份验证的加密被认为是单层保护;
- 应用数字签名时,使用通用签名APDU。
如果同一方对同一方应用了加密和数字签名,则通常先应用数字签名。
通用加密和通用签名apdu都包括Originator_System_Title和Recipient_System_Title,标识应用保护的一方和检查/删除保护的一方。
对响应应用的保护取决于响应的安全策略和访问权限以及对请求应用的保护。如果对一方当事人的请求已经适用了一种保护,则在答复中将对同一方当事人适用同样的保护。但是,如果对请求适用的某种保护对答复不需要,则对该当事方的答复不适用保护。
示例1如果请求由第三方进行数字签名,并由客户端进行身份验证,并且响应所需的保护是身份验证和数字签名,则响应将为客户端进行身份验证,并为第三方进行数字签名。
示例2如果请求由第三方进行数字签名并由客户端进行身份验证,并且对响应所要求的保护仅为身份验证,则响应将为客户端进行身份验证,而不对第三方应用任何保护。(TP将接收一个没有任何保护的通用加密APDU。)
如果需要对未应用于请求的响应进行保护,则服务器无法从请求中确定哪一方拥有需要保护的响应。因此,它应适用于所有当事人的保护。另见附件D。
9.2.7.4 HLS authentication mechanisms
HLS身份验证需要对客户机和服务器之间交换的请求进行加密处理。HLS身份验证机制
、交换的信息
和处理交互的公式
如表42所示。
Authentication mechanism | Pass 1:C→S | Pass 2:S→C | Pass 3:C→S f(StoC) | Pass 4:S→C f(CtoS) |
---|---|---|---|---|
Carried by | ||||
AARQ | AARE | XX.request reply_to_HLS authentication | XX.response reply_to_HLS authentication | |
mechanism_id(2) HLS man. Spec. | CtoS: Random string 8-64 octets | StoC: Random string 8-64 octets | Man. Spec. | Man. Spec. |
mechanism_id(3) HLS MD51 | MD5(StoC || HLS Secret) | MD5(CtoS || HLS Secret) | ||
mechanism_id(4) HLS SHA-11 | MD5(StoC || HLS Secret) | SHA-1(CtoS || HLS Secret) | ||
mechanism_id(5) HLS GMAC | CtoS:Random string 8-64 octets Optionally:System-Title-C in calling-AP-title | StoC:Random string 8-64 octets Optionally:System-Title-S in responding-AP-title | SC || IC || GMAC(SC || AK || StoC) | SC || IC || GMAC(SC || AK || CtoS) |
mechanism_id(6) HLS SHA-256 | SHA-256(HLS_Secret || SystemTitle-C || SystemTitle-S || StoC || CtoS) | SHA-256(HLS_Secret || SystemTitle-S || SystemTitle-C || CtoS || StoC) | ||
mechanism_id(7) HLS ECDSA | CtoS: Random string 32 to 64 octets Optionally:System-Title-C in calling-AP-title,Cert-Sign-Client in calling-AE-qualifier | StoC: Random string 32 to 64 octets Optionally:System-Title-S in responding-AP-title,Cert-Sign-Server responding-AE- qualifier | ECDSA(SystemTitle-C || SystemTitle-S || StoC || CtoS) | ECDSA(SystemTitle-S || SystemTitle-C || CtoS || StoC) |
- C: Client, S: Server, CtoS: Challenge client to server, StoC: Challenge server to client - IC: Invocation counter - xx.request / .response: 用于访问"关联SN / LN"对象的reply_to_HLS身份验证方法的xDLMS服务原语。 | ||||
(1)不建议在新的实现中使用身份验证机制3和4。 | ||||
需要提前知道对方的证书和 systemtitle,不知道的话需要传递 |
如果还需要数字签名密钥的系统标题和证书,则可以在AARQ / AARE apdu中传输这些内容,并携带COSEM-OPEN服务.request / .response,参见图64。System_Title和Cert-Sign可能是已知的;在这种情况下,它们不需要运输。如果不具备这些要素,则质疑的处理结果失败,AA不能建立。
Security material | X | Contents | LEN(X)bytes | len(X) bits | |
---|---|---|---|---|---|
Security suite | GCM-AES-128 | ||||
System Title | Sys-T | Client | Server | ||
4D4D4D0000000001 | 4D4D4D0000BC614E | ||||
(这里,最后五个字节包含十六进制的制造编号) | 8 | 64 | |||
Invocation counter | IC | 00000001 | 01234567 | 4 | 32 |
Initialization Vector | IV | Sys-T|| IC | 12 | 96 | |
Client | Server | ||||
4D4D4D0000000001 00000001 | 4D4D4D0000BC614E 01234567 | ||||
Block cipher key (global) | EK | 000102030405060708090A0B0C0D0E0F | 16 | 128 | |
Authentication Key | AK | D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF | 16 | 128 | |
Security control byte | SC | 10 | 1 | 8 | |
Pass 1: Client sends challenge to server | |||||
CtoS | 4B35366956616759 "K56iVagY" | 8 | 64 | ||
Pass 2: Server sends challenge to client | |||||
StoC | 503677524A323146 "P6wRJ21F" | 8 | 64 | ||
Pass 3: Client processes StoC | |||||
SC||AK||StoC | 10D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF503677524A323146 | ||||
T = GMAC (SC||AK IIStoC) | 1A52FE7DD3E72748973C1E28 | 12 | 96 | ||
f(StoC) = SC||IC||T | 10000000011A52FE7DD3E72748973C1E28 | 17 | 136 | ||
Pass 4: Server processes CtoS | |||||
SC||AK||CtoS | 10D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF4B35366956616759 | ||||
T (SC||AK||CtoS) | FE1466AFB3DBCD4F9389E2B7 | 12 | 96 | ||
f(CtoS) = SC||IC||T | 1001234567FE1466AFB3DBCD4F9389E2B7 | 17 | 136 |
表44提供了具有ECDSA的HLS认证机制7的使用示例。
Security Material | X | Contents | LEN (Bytes) |
---|---|---|---|
Security Suite | ECDH-ECDSA-AES-128-GCM | ||
Curve | P-256 | ||
Domain Parameters | D | See Table A. 1. | |
System Title Client | Sys-TC | 4D4D4D0000BC614E | 8 |
System Title Server | Sys-TS | 4D4D4D0000000001 | 8 |
Private Key Client | Pri-KC | E9A045346B2057F1820318AB125493E9AB36CE590011C0FF30090858A118DD2E | 32 |
Private Key Server | Pri-KS | B582D8C910018302BA3131BAB9BB6838108BB9408C30B2E49285985256A59038 | 32 |
Public Key Client | Pub-KC | 917DBFECA43307375247989F07CC23F53D4B963AF8026C749DB33852011056DFDBE8327BD69CC149F018A8E446DDA6C55BCD78E596A56D403236233F93CC89B3 | 64 |
Public Key Server | Pub-KS | E4D07CEB0A5A6DA9D2228B054A1F5E295E1747A963974AF75091A0B0BC2FB92DA7D2ABD9FDD41579F36A1C8171A0CB638221DF1949FD95C8FAE148896920450D | 64 |
Challenge Client To Server | CtoS | 2CA1FC2DE9CD03B5E8E234CEA16F2853F6DC5F54526F4F4995772A50FB7E63B3 | 32 |
Challenge Server To Client | StoC | 18E95FFE3AD0DCABDC5D0D141DC987E270CB0A395948D4231B09DE6579883657 | 32 |
ECDSA(SystemTitle-C || SystemTitle-S ||StoC || CtoS)(calculated with Pri-KC) | f(StoC) | C5C6D6620BDB1A39FCE50F4D64F0DB712D6FB57 A64030B0C297E1250DC859660D3B1FA334AD80411807369F5DD3BC17B59894C9E9C11C59376580D15A2646D16 | 64 |
ECDSA(SystemTitle-S || SystemTitle-C || CtoS || StoC)(calculated with Pri-KS) | f(CtoS) | 946C2E3E4F18291571F4A45ACB7086100574694 A3BAF67D2D147FE8F92481A5AB2186C5CBC3F80 E94482D9388B85C6A73E5FD687F09773C1F615A A2A905ED057 | 64 |
注:公钥的值在这里表示为FE2OS(xp)||FE2OS(yp)。 |
9.2.7.5 Protecting COSEM data
应用于xDLMS apdu的加密算法也可以应用于COSEM数据,即属性值和方法调用/返回参数。这是通过通过"数据保护"接口类的实例间接访问其他COSEM对象的属性和/或方法来实现的,参见DLMS UA 1000-1 Ed. 12.2: 2017,4.4.9。
需要保护的数据列表、保护要求和保护参数由"数据保护"对象确定。"数据保护"对象允许在读取或写入属性列表或调用COSEM对象的方法时应用或删除保护。要应用/取消的保护可以包括身份验证、加密和数字签名的任何组合。
承载访问"Data protection"对象的属性和方法的服务调用的apdu按照当前的安全策略和"Data protection"对象的访问权限进行保护
9.3 DLMS/COSEM application layer service specification
9.3.1 Service primitives and parameters
一般来说,一层(或子层)的服务是它向下一层(或子层)中的用户提供的功能。为了提供自己的服务,一个层将自己的功能建立在它需要下一层提供的服务之上。图86说明了服务层次结构的概念,并显示了两个对应的n个用户及其关联的n层对等协议实体之间的关系。
通过描述N-user和N-layer之间的信息流来指定服务。该信息流由离散的瞬时事件建模,这些事件表示了服务的提供。每个事件都包括通过与N-user关联的N-layer接入点将服务原语从一层传递到另一层。服务原语传递提供特定服务所需的信息。这些服务原语是抽象的,因为它们只指定所提供的服务,而不指定提供服务的方式。服务的定义独立于任何特定的接口实现。
服务是通过描述描述每个服务的服务原语和参数来指定的。服务可以有一个或多个相关的原语,这些原语构成了与特定服务相关的活动。每个服务原语可以有0个或多个参数,这些参数传递提供服务所需的信息。
- 基元有四种泛型类型:
- REQUEST:请求原语从 N-user传递到N-layer以请求启动服务;
- INDICATION :指示原语从N-layer传递给 N-user,以指示对 N-user重要的内部N-layer事件。 该事件可能逻辑上与远程服务请求有关,也可能是N-layer内部的事件引起的;
- RESPONSE :响应原语从 N-user传递到N-layer,以完成先前由指示原语调用的过程。
- CONFIRM :确认原语从 N-layer传递给N-user,以传达一个或多个相关的先前服务请求的结果。
图87所示的时间序列图说明了基本类型之间可能存在的关系。该图还指出了基本类型之间的逻辑关系。在时间上较早出现并在图中通过虚线连接的原语类型是后续原语类型的逻辑先行项。




DLMS/COSEM AL服务原语的服务参数以表格格式表示。每个表由两到五列组成,这些列描述服务原语及其参数。在每个表中,每行列出一个参数或参数的一部分。在适当的服务原语列中,使用代码指定参数的使用类型。所使用的代码列在表45中。
某些参数可能包含子参数。通过将参数标记为M、U、S或C,并将参数下的所有子参数缩进来表示这些参数。子参数的存在总是依赖于它们所对应的参数的存在。例如,一个可选参数可以有子参数;如果未提供参数,则不能提供子参数。
M | 该参数对于原语是必需的。 |
U | 该参数是一个用户选项,根据ASE用户的动态使用情况,可以提供也可以不提供。 |
S | 从其他S-parameters参数中选择该参数作为服务器ASE环境的内部响应 |
C | 该参数取决于其他参数或ASE用户所在的环境。 |
C | 该参数永远不存在 |
= | (=)跟随在M、U、S或C后面,表示该参数在语义上等同于表中紧邻其左侧的服务原语中的参数。 例如,"M(=)"在.indication服务原语列中的代码和.request服务原语列中的"M" 意味着.indication原语中的参数在语义上等同于.request原语中的参数。 |
- 在本技术报告中,术语的命名遵循以下规则:
- 使用LN referencing的ACSE服务和数据传输服务的名称用大写字母书写。例如:COSEM-OPEN, GET;
- 使用SN referencing的数据传输服务的名称以标题形式书写。例如:Read, Write;
- 骆驼符号用于以下情况:DataNotification, EventNotification, TriggerEventNotificationSending, UnconfirmedWrite, InformationReport;
- LN服务原语的类型可能以两种替代形式提到。例如 GET.request是Request_Type == NORMAL或者GET-REQUEST-NORMAL的服务原语
- 服务参数名称元素大写,并用下划线连接以表示单个实体:例如Protocol_Connection_Parameters和COSEM_Attribute_Descriptor;
- 当相同的参数可能出现多次时,通过在花括号中重复参数来表示。示例:Data {Data};
- 在数据传输服务规范中,仅用于块传输的参数以粗体显示。例如:DataBlock_G;
说明仅适用于特定于业务的块传输机制。
- 对服务参数的直接引用使用大写形式,而间接(非特定)引用使用没有下划线连接的小大写。一个直接引用的例子是:"COSEM_Attribute_Descriptor参数引用COSEM对象属性。"一个间接的(非特定的)引用示例是:"GET-REQUEST-NORMAL服务原语包含单个COSEM属性描述符";
- 使用LN referencing的COSEM数据传输apdu的名称大写,并用破折号连接以表示单个实体。例如:Get-Request-Normal;
- 使用SN referencing的COSEM数据传输apdu的名称使用驼峰符号。例子:ReadRequest。
9.3.2 The COSEM-OPEN service
COSEM-OPEN 服务的作用是在对端 COSEM 应用实体(AEs)之间建立 AA。它使用ACSE的A-ASSOCIATE服务。COSEM-OPEN服务仅提供用于传输此信息的框架。提供和验证该信息是适当的COSEM AP的工作。
COSEM-OPEN服务原语应该提供如表46所示的参数
Table 46 – Service parameters of the COSEM-OPEN service primitives
.request | .indication | .response | .confirm | |
Use_RLRQ_RLRE | U | C(=) | C(=) | - |
Reason | U | U (=) | U | U (=) |
Proposed_xDLMS_Context | C | C (=) | – | – |
Negotiated_xDLMS_Context | – | – | C | C (=) |
Local_Or_Remote | – | – | – | M |
Result | – | – | M | M |
Failure_Type | – | – | – | C |
User_Information | U | C (=) | U | C (=) |
- 使用
-
COSEM-OPEN的服务参数的
COSEM-OPEN.request
原语,除了Protocol_Connection_Parameters、User_Information参数和Service_Class参数(取决于通信配置文件)外,都由客户端发送的AARQ APDU的字段携带。 -
COSEM-OPEN的服务参数的
COSEM-OPEN.response
原语,除了Protocol_Connection_Parameters是由服务器发送的AARE APDU的字段携带。 -
A-ASSOCIATE服务、AARQ和AARE apdu在9.4.2中指定。编码示例在11中给出。
-
Protocol_Connection_Parameters
为必选参数。它包含使用通信配置文件各层所需的所有信息,包括通信配置文件(协议)标识符和所需的地址。标识了AA的参与者。此参数的元素将传递给管理较低层连接的实体,并酌情传递给较低层。 -
ACSE_Protocol_Version
是可选参数。如果存在,则应使用缺省值。 -
Application_Context_Name
必选参数。在请求原语中,它保存客户端建议的值。在响应原语中,它保存相同的值或服务器支持的值。类似于TLS握手中的加密策略,是一个需要协商的值
-
Called_AP_Title
、Called_AE_Qualifier
、Called_AP_Invocation_Identifier
,Called_AE_Invocation_Identifier
参数的使用是可选的。本技术报告未说明其用途。Calling_AP_Title
参数的使用是有条件的。当Application_Context_Name表示使用加密的应用程序上下文时,它可以携带4.3.4中指定的客户端系统标题。Calling_AE_Qualifier
参数的使用是有条件的。当Application_Context_Name表示使用加密的应用程序上下文时,它可以携带客户端的公共数字签名密钥证书。Calling_AP_Invocation_Identifier
参数的使用是可选的。本技术报告未说明其用途。Calling_AE_Invocation_Identifier
参数的使用是可选的。当出现时,它携带AA的客户端用户标识符。
注1客户端用户识别机制在DLMS UA 1000-1版本12.2:2011,4.4.2中规定。
-
Local_or_Remote
是必选参数。他代表着COSEM-OPEN.confirm原语的起源 。如果原语是在从服务器接收到AARE APDU之后生成的,则将其设置为Remote。如果原语是在本地生成的,则将其设置为Local。 -
Result
为必选参数。在远程确认的情况下,表示服务器是否接受提议的AA。在本地确认的情况下,它指示客户端协议栈是否接受请求。 -
Failure_Type
是必选参数。在远程确认的情况下,它携带服务器提供的信息。在本地确认和否定确认的情况下,表示失败的原因。 -
Responding_AP_Title
参数的使用是有条件的。当Application_Context_Name参数表示使用加密的应用程序上下文时,它可以携带4.3.4中指定的服务器系统标题。 -
Responding_AE_Qualifier
参数的使用是有条件的。当Application_Context_Name表示使用加密的应用程序上下文时,它可以携带服务器的公共数字签名密钥证书。 -
Responding_AP_Invocation_Identifier
和Responding_AE_Invocation_Identifier
参数的使用是可选的。本技术报告未说明其用途。 -
ACSE_Requirements
是可选参数。为关联选择A-Associate服务的可选认证功能单元。见9.4.2.1。
ACSE_Requirements参数的存在取决于所使用的认证机制:- 在最低级别安全认证的情况下,不应出现;只使用内核功能单元;
- 在低级别安全(LLS)认证的情况下,它应该出现在.request原语中,它可能出现在.response服务原语中,它应该表明认证(bit 0设置);
- 在高级安全(HLS)身份验证的情况下,它应该同时出现在.request和.response服务原语中,并且它应该表示认证(bit 0设置)。
-
Security_Mechanism_Name
参数为必选参数。只有在选择了认证时才会出现。如果存在,.request原语保存客户端提议的值,.response原语保存服务器要求的值,即客户端要使用的值。 -
Calling_Authentication_Value
和Responding_Authentication_Value
是必选参数。只有在选择了身份验证功能单元的情况下,它们才会出现。它们分别保存适合Security_Mechanism_Name的客户端身份验证值/服务器身份验证值。 -
Implementation_Information
是可选参数。本技术报告未说明其用途。 -
Proposd_xDLMS_Context
参数保存提议的xDLMS上下文的元素。它由xDLMS InitiateRequest APDU携带,放在AARQ APDU的用户信息字段中。 -
Dedicated_Key
元素是有条件的。只有当Application_Context_Name
参数表示使用加密的应用程序上下文时,它才可能出现。专用密钥用于对建立的AA内交换的xDLMS apdu进行专用加密。 -
当
Dedicated_Key
存在时,应该使用AES-GCM算法、全局单播加密密钥和AK(如果使用)对xDLMS InitiateRequest APDU进行认证和加密。此外,如果安全策略要求,还应对其进行数字签名。 -
当
Dedicated_Key
不存在时,xDLMS InitiateRequest APDU应以与上述相同的方式受到保护,但有必要通过在其user-information字段中包含受保护的xDLMS InitiateRequest来保护RLRQ APDU。见9.3.3。 -
Response_Allowed
元素的使用是有条件的。它表示是否允许服务器响应AARE APDU,即要建立的AA是否被确认(Response_Allowed == TRUE)或未被确认(Response_Allowed == FALSE)。 -
Proposed_DLMS_Version_Number
元素保存提议的DLMS版本号。见9.1.4。 -
Proposed_DLMS_Conformance
元素保存提议的一致性块。见9.4.6.1。 -
Client_Max_Receive_PDU_Size
元素保存客户端可以接收的xDLMS APDUs的最大长度。见表12如果客户端提出的xDLMS上下文对于服务器是可接受的,那么响应服务原语应该包含Negotiated_xDLMS_Context参数。它由xDLMS initiaterresponse APDU携带,放在AARE APDU的用户信息字段中。如果xDLMS InitiateRequest APDU已经加密,xDLMS initiaterresponse APDU也应该以同样的方式加密。
-
Negotiated_DLMS_Version_Number
元素保存协商后的DLMS版本号。见9.1.4。 -
Negotiated_DLMS_Conformance
元素保存协商的一致性块。见9.4.6.1。 -
Server_Max_Receive_PDU_Size
元素携带服务器可以接收到的xDLMS appdu的最大长度。见表12。 -
在LN referencing的情况下,
VAA_name
元素携带值0x0007,在SN referencing的情况下,VAA_name
元素携带当前关联对象的base_name 0xFA00。 -
如果客户机提出的xDLMS上下文对于服务器来说是不可接受的,那么响应服务原语应该携带
xDLMS_Initiate_Error
参数。它由confirmedServiceError APDU携带,带有适当的诊断元素,放置在AARE APDU的用户信息字段中。 -
User_Information
是可选参数。如果存在,则应传递给支持的那层,前提是支持的那层能够携带。指示原语应该包含由支持的较低协议层携带的用户特定信息。见第10条。COSEM-OPEN服务的User_Information参数不能与AARQ / AARE apdu的user-information字段混淆。
-
Service_Class
是必选参数。它指示服务是以已确认的方式调用还是以未确认的方式调用。此参数的处理可能取决于通信配置文件。见第10条。 -
COSEM-OPEN服务原语的可能逻辑序列如图87所示。
- 对于已确认的AA -成功或不成功-建立,a)项;
- 对于未经确认的AA建立,b)项;
- 在预先建立的AA或由于本地错误导致的失败尝试的情况下,c)项。
-
客户端AP调用.request原语,请求与服务器AP建立已确认或未确认的AA。
在调用COSEM-OPEN之前。请求原语时,物理层必须连接。根据通信配置文件的不同,调用此原语也可能意味着连接其他较低的层。
在接收到请求调用后,AL构造一个AARQ APDU并将其发送到服务器。
当接收到格式正确的AARQ APDU时,服务器AL会生成.indication原语。 -
服务器AP调用.response原语,以指示AL是否接受提议的AA。只有当提议的AA得到确认时,才会调用它。然后,该AL构造一个AARE APDU并将其发送给对等体,其中包含从该AP接收到的服务参数。
-
.confirm原语由客户端AP生成,用于向客户端AP指示先前请求的AA是否被接受:
- 远程, 接收到AARE APDU时;
- 本地,如果请求的AA已经存在;这包括预先建立的aa;
- 本地,如果对应的.request原语已经被Service_Class == Unconfirmed调用;
- 本地,如果请求的AA不被允许;
- 本地,如果检测到错误:缺少或不正确的参数,在建立请求的下层连接期间失败,缺少物理连接等。
9.4.4中规定了建立AA的协议。通信配置文件的具体规则见第10条。
9.3.3 The COSEM-RELEASE service
优雅释放已经存在的AA调用它的方式(Use_RLRQ_RLRE 参数)决定了它是否使用ACSE
的A-RELEASE
服务。
.request | .indication | .response | .confirm | |
---|---|---|---|---|
Use_RLRQ_RLRE | U | C(=) | C(=) | - |
Reason | U | U (=) | U | U (=) |
Proposed_xDLMS_Context | C | C (=) | – | – |
Negotiated_xDLMS_Context | – | – | C | C (=) |
Local_Or_Remote | – | – | – | M |
Result | – | – | M | M |
Failure_Type | – | – | – | C |
User_Information | U | C (=) | U | C (=) |
如果 Use_RLRQ_RLRE 为 FALSE,则 AL 层不能使用 A-RELEASE 服务中的RLRQ和RLRE (和AARQ/AARE 相对,见 9.4.2.1),也就不能使用 RLRQ/RLRE断链。可以通过断开支持层的方式断链
request原语中的Use_RLRQ_RLRE
参数是可选的。如果存在,它的值可能是FALSE(默认)或TRUE。它指示是否应该使用ACSE A-RELEASE服务(涉及RLRQ /RLRE APDU交换)。A-RELEASE服务和RLRQ/RLRE APDUs在9.4.2中指定。response原语中的Use_RLRQ_RLRE参数是有条件的。
如果它出现在指示原语中并且其值为TRUE,则它也应该出现并且其值为TRUE。否则,它将不存在或其值为FALSE。
如果Use_RLRQ_RLRE参数的值为FALSE,则可以通过断开AL的支持层来释放AA。
Reason为可选参数。只有当Use_RLRQ_RLRE的值为TRUE时才会出现。分别由RLRQ/RLRE APDU的reason字段携带。
- 当在.request原语上使用时,该参数标识请求的一般紧急级别。它接受以下符号值之一:
- 正常;
- 紧急(DLMS/COSEM不提供);或
- 用户定义。
- 当在.response原语上使用时,此参数标识有关接受者接受或拒绝发布请求的原因的信息。注意,在DLMS/COSEM中,服务器不能拒绝发布请求。它接受以下符号值之一:
- 正常;
- 未完成;或
- 用户定义。
当接受者被强制释放关联,但希望给出一个警告,表示它有额外的信息要发送或接收时,在.response原语中使用值" not finished"。
-
Proposed_xDLMS_Context
参数是有条件的。只有当Use_RLRQ_RLRE的值为TRUE并且要释放的AA已经通过使用加密的应用程序上下文建立时才会出现。此选项允许保护COSEM-RELEASE服务,从而避免可能因未经授权发布AA而进行的拒绝服务攻击。
在.request原语中,Proposed_xDLMS_Context
参数应与COSEM-OPEN.request中的参数相同。请求服务原语,建立要发布的AA。它由xDLMS InitiateRequest APDU携带,与AARQ中的保护方式相同,并放置在RLRQ APDU的用户信息字段中。
如果xDLMS InitiateRequest APDU可以被成功解密,那么.response原语应该携带与COSEM-OPEN.request中相同的Negotiated_xDLMS_Context
参数相同的相应。它由xDLMS initiaterresponse APDU携带,受到与AARE相同的保护,并放置在RLRE APDU的用户信息字段中。
否则,RLRQ APDU将被静默丢弃。 -
Local_or_Remote是必选参数。它指示COSEM-RELEASE.confirm的起源
- 如果有以下情况,则设置为Remote:
- RLRE APDU已从服务器接收;或
- 断开连接确认服务原语已被接收。
如果原语是在本地生成的,则将其设置为Local。
-
Result
为必选参数。在.response原语中,它指示服务器AP是否可以接受释放AA的请求。由于服务器不能拒绝这样的请求,它的值通常应该是SUCCESS,除非引用的AA不存在。 -
Failure_Type
是必选参数。如果Result == ERROR,则显示该错误。在本例中,它指示失败的原因。它是客户端本地生成的参数。 -
.request原语中的
User_Information
参数是可选的。如果存在,则将其传递到支持的层,只要它能够携带它。指示原语包含由支持的较低协议层携带的用户特定信息。类似地,它在.response原语中也是可选的。如果存在,则传递给支持的层。在.confirm原语中,它可能只在远程确认服务时出现。然后,它包含由支持较低协议层携带的特定于用户的信息。COSEM-RELEASE服务的User_Information参数不能与RLRQ / RLRE apdu的User_Information字段混淆。
-
User_Information参数内容的规范不在本技术报告的范围之内。另见第10条。
-
COSEM-RELEASE服务原语的可能逻辑序列如图87所示:
- 对于已确认的AA的成功放行,a)项;
- 对于未经确认的AA的放行,b)项;和
- 由于本地错误项c)导致的失败尝试。
-
COSEM-RELEASE服务的使用取决于Use_RLRQ_RLRE参数的值。当使用Use_RLRQ_RLRE == TRUE调用该服务时,该服务基于ACSE A-RELEASE服务。否则,服务的调用将导致支持层的断开。
request原语由客户端AP调用,请求服务器AP释放已确认或未确认的AA。在接收到Use_RLRQ_RLRE == TRUE的请求调用后,AL构造并向服务器发送RLRQ APDU。否则,它发送一个XX-DISCONNECT。请求原语(其中XX是支持的较低协议层)。
- 在下列情况下,.indication原语由服务器AL生成:
- 收到RLRQ APDU。如果出现解码错误,RLRQ APDU将被静默丢弃(非.indication原语生成的);或
- 一个XX-DISCONNECT。请求被接收。
- .response原语由服务器AP调用,但只有在确认要释放的AA时才会调用。注意,服务器AP不能拒绝此请求。服务器AL在接收到.response服务原语后:
- 如果Use_RLRQ_RLRE参数为TRUE,则发送RLRE APDU;或
- 发送一个XX-DISCONNECT。否则响应。
- .confirm原语由客户端AP生成,以指示客户端AP是否接受所请求的AA释放:
- 当远程接收到XX-DISCONNECT.cnf原语时。支持的层断开;或
- 当远程接收到RLRE APDU时。支持的层不断开;或
- 本地,在等待RLRE APDU的超时时间届满时;或
- 本地,当发送RLRQ APDU以释放未确认的AA时;或
- 本地,当本地错误被检测到:丢失或不正确的参数,或通信失败在较低的协议层等。
如果收到的RLRE APDU包含加密的xDLMS initiaterresponse APDU,但无法解密,则丢弃该RLRE APDU。留给客户来处理的情况。
释放AA的协议在9.4.5中指定。通信配置文件特定规则在10中指定。参见9.4.2。
9.3.4 The COSEM-ABORT service
COSEM-ABORT服务的功能是指示支持层的非请求断开。
服务原语的语义
COSEM-ABORT服务原语应提供如表48所示的参数(对应上图中的e情况
)。
.indication | |
---|---|
Diagnostics | U |
Diagnostics
为可选参数。它应该表明断开连接的可能原因,也可以携带依赖于较低协议层的信息。该参数内容的说明不在本技术报告的范围内。
COSEM-ABORT.indication原语是在客户端和服务器端本地生成的,用于向COSEM AP指示较低层连接以非请求的方式关闭。当支持层连接不受DLMS/COSEM AL管理时,此类事件的起源可以是外部事件(例如物理线路中断),也可以是某些配置文件中存在的支持层连接管理器AP的动作。这将导致COSEM AP中止任何现有的AAs,除了服务器端预先建立的AAs。
9.3.5 Protection and general block transfer parameters
为了控制xDLMS apdu的加密保护和GBT机制,在AL和AP之间传递额外的服务参数,如图88和表49所示。
Additional_Service_Parameters 仅在使用 加密 或 GBT 时存在。

对于由客户端发起的服务,服务原语是.request、.indication、.response和.confirm。对于未经请求的服务(由服务器发起),服务原语是.request和.indication。
.request | .indication | .response | .confirm | |
---|---|---|---|---|
Additional_Service_Parameters | U | – | U (=) | |
Invocation_Type | M | – | M (=) | – |
Security_Options | C | – | C (=) | – |
General_Block_Transfer_Parameters | C | – | C (=) | – |
Block_Transfer_Streaming | M | – | M (=) | – |
Block_Transfer_Window | M | – | M (=) | – |
Service_Parameters | M | – | M (=) | – |
Additional_Service_Parameters | – | U | – | U (=) |
Invocation_Type | – | U | – | U (=) |
Security_Status | – | C | – | C (=) |
General_Block_Transfer_Parameters | – | C | – | C (=) |
Block_Transfer_Window | – | M | – | M (=) |
Service_Parameters | – | M | – | M (=) |
Protection_Element | – | C | – | C (=) |
可用的服务原语取决于服务的类型 |
只有在使用加密
或GBT
时才会出现Additional_Service_Parameters
。
Invocation_Type
参数是必选的:它指示服务调用是完整的还是部分的。可能的值:COMPLETE, FIRST-PART, ONE-PART和LAST-PART。
注1:当服务参数较长时,部分服务调用可能有用。但是,部分服务调用和通用块传输apdu之间没有直接关系
Security_Options
参数是有条件的:只有当应用程序上下文是加密的,.request / .response服务原语必须加密,并且Invocation_Type =COMPLETE或FIRST-PART时才会出现。它决定了AL的保护。参见表50、9.4.6.13和图111。General_Block_Transfer_Parameters
参数是有条件的:它只在使用通用块传输(GBT)并且Invocation_Type = COMPLETE或FIRST-PART时出现。它提供了有关GBT流媒体功能的信息:Block_Transfer_Streaming
参数只存在于.request和.response服务原语中。它由AP传递给AL,以指示AL是否允许使用流式传输发送通用块传输apdu (TRUE 允许使用)或(FALSE 不允许使用);Block_Transfer_Window
参数表示支持的窗口大小,即在一个窗口中可以接收的最大块数。流进程本身由AL管理,参见9.4.6.13。
Service_Parameters
是必需的:它们包括xDLMS服务调用的参数。如果Invocation_Type!= COMPLETE,则它包含部分服务参数。Security_Status
参数是有条件的:只有在应用了加密保护时才会出现。它携带关于AL已验证/删除的保护的信息。它可能出现在所有类型的服务调用中。见表50。Protection_Element
参数是有条件的:只有当APDU经过认证或签名时才会出现。见表50。
.request | .indication | .response | .confirm | |||||
Security_Options | C | – | C (=) | – | ||||
Security_Options_Element{Security_Options_Element} | M | – | M (=) | – | ||||
Security_Protection_Type | M | – | M (=) | – | ||||
Glo_Ciphering | S | – | S (=) | – | ||||
Ded_Ciphering | S | – | S (=) | – | ||||
General_Glo_Ciphering | S | – | S (=) | – | ||||
General_Ded_Ciphering | S | – | S (=) | – | ||||
General_Ciphering | S | – | S (=) | – | ||||
General_Signing | S | – | S (=) | – | ||||
With General_Glo_Ciphering and General_Ded_Ciphering | ||||||||
---|---|---|---|---|---|---|---|---|
System_Title | U | – | U (=) | – | ||||
With General_Ciphering and General_Signing | ||||||||
Transaction_Id | U | – | U (=) | – | ||||
Originator_System_Title | U | – | U (=) | – | ||||
Recipient_System_Title | U | – | U (=) | – | ||||
Date_Time | U | – | U (=) | – | ||||
Other_Information | U | – | U (=) | – | ||||
With General_Ciphering | ||||||||
Key_Info_Options | C | – | C (=) | – | ||||
Identified_Key_Options | S | – | S (=) | – | ||||
Wrapped_Key_Options | S | – | S (=) | – | ||||
Agreed_Key_Options | S | – | S (=) | – | ||||
With Glo_Ciphering, Ded_Ciphering, General_Glo_Ciphering, General_Ded_Ciphering, General_Ciphering | ||||||||
Security_Control | M | – | M (=) | – | ||||
Security_Status | – | C | – | C (=) | ||||
Security_Status_Element{Security_Status_Element} | – | M | – | M (=) | ||||
Security_Protection_Type | M | M (=) | ||||||
Glo_Ciphering | – | S | – | S (=) | ||||
Ded_Ciphering | – | S | – | S (=) | ||||
General_Glo_Ciphering | – | S | – | S (=) | ||||
General_Ded_Ciphering | – | S | – | S (=) | ||||
General_Ciphering | – | S | – | S (=) | ||||
General_Signing | – | S | – | S (=) | ||||
With General_Glo_Ciphering and General_Ded_Ciphering | ||||||||
System_Title | – | U | – | U (=) | ||||
With General_Ciphering and General_Signing | ||||||||
Transaction_Id | – | U | – | U (=) | ||||
Originator_System_Title | – | U | – | U (=) | ||||
Recipient_System_Title | – | U | – | U (=) | ||||
Date_Time | – | U | – | U (=) | ||||
Other_Information | – | U | – | U (=) | ||||
With General_Ciphering | ||||||||
Key_Info_Status | – | C | – | C (=) | ||||
Identified_Key_Status | – | S | – | S (=) | ||||
Wrapped_Key_Status | – | S | – | S (=) | ||||
Agreed_Key_Status | – | S | – | S (=) | ||||
With Glo_Ciphering, Ded_Ciphering, General_Ded_Ciphering, General_Glo_Ciphering, General_Ciphering | ||||||||
Security_Control | – | M | – | M (=) | ||||
The protection element is present when authentication or digital signature is applied. | ||||||||
Protection_Element {Protection_Element} | – | C | – | C (=) | ||||
Invocation_Counter | – | C | – | C (=) | ||||
Authentication_Tag | – | C | – | C (=) | ||||
Signature | – | C | – | C (=) |
Security_Options
参数包含一个Security_Options_Element
参数,对应应用的每种保护。类似地,Security_Status
参数为每一种已应用的保护包含一个Security_Status_Element
参数。参见9.2.7.3。
- 参数
Security_Options_Element
和Security_Status_Element
包括以下子参数:
Security_Protection_Type
子参数是必选的:它标识要使用的加密APDU;见表51;System_Title
子参数为可选参数。当出现时,它保存发送者的系统标题。它只能与General_Glo_Ciphering
和General_Ded_Ciphering
一起出现;
包含
System_Title
名称的目的是允许另一方在媒体特定注册过程或AARQ / AARE交换期间未交换System_Title
的情况下构建初始化向量(IV)
Table 51 – APDUs used with security protection types
Security_Protection_Type | APDU |
---|---|
Glo_Ciphering | Service-specific glo-ciphering |
Ded_Ciphering | Service-specific ded-ciphering |
General_Glo_Ciphering | general-glo-ciphering |
General_Ded_Ciphering | general-ded-ciphering |
General_Ciphering | general-ciphering |
General_Signing | general-signing |
See also Table 36
- 以下五个参数可选地出现在
General_Ciphering和General_Signing
中:
- Transaction_Id:标识双方之间的交易;
- Originator_System_Title:受保护APDU发起者的系统名称;
- Recipient_System_Title:收件人的系统标题,即将验证/删除已应用于APDU的保护的实体。在广播的情况下,Recipient_System_Title应该是一个空字符串;
- Date_Time为可选参数。当出现时,它指示调用.request / .response服务原语的日期和时间。除非项目的配套规范另有规定,如在要求中有日期时间参数,则应在回应中出现;如在要求中没有日期时间参数,则不应在回应中出现;
- Other_Information为可选参数。当出现时,它包含有关保护的附加信息。其内容可在项目具体配套规范中规定;
如果不使用上述任何参数,则应包含长度为零的八位字节串。
Key_Info_Options
参数是有条件的:当必须应用保护时,它携带关于发送方已经使用/接收方将要使用的对称密钥的信息。密钥信息作为加密APDU的一部分发送/接收:
Identified_Key_Options
(见9.2.5.3):它可以在合作伙伴共享密钥时使用;这可以是全局单播加密密钥或全局广播加密密钥;Wrapped_Key_Options
(见9.2.5.4):在这种情况下,发送一个封装的密钥;Agreed_Key_Options
(见9.2.5.5):在这种情况下,合作伙伴使用Diffie-Hellman密钥协商方案来商定密钥;
Security_Control:包含安全控制字节,见表37。
Protection_Element
参数是有条件的:如果APDU已经验证或数字签名,则该参数必须存在。它可能出现在所有类型的服务调用中,但如果它还不可用,它可能是空的(这可能发生在使用一般块传输的情况下)。-它包含:
- 在General_Ciphering的情况下,Invocation_Counter保存初始化向量的调用字段,参见9.2.3.3.7.3;
- 在APDU已被认证的情况下,认证标签;
- 在APDU已签名的情况下,为数字签名。
9.3.6 The GET service
GET服务与LN referencing一起使用。它可以以已确认或未确认的方式调用。它的功能是读取一个或多个COSEM对象属性的值。结果可以在单个响应中交付,或者(如果它太长,不能在单个响应中交付)在多个响应中交付,使用块传输 (没有指定是那种类型的块传输)。
GET服务原语应提供如表52所示的参数。
.request | .indication | .response | .confirm | |
---|---|---|---|---|
Invoke_Id | M | M (=) | M (=) | M (=) |
Priority | M | M (=) | M (=) | M (=) |
Service_Class | M | M (=) | M (=) | M (=) |
Request_Type | M | M (=) | – | – |
COSEM_Attribute_Descriptor { COSEM_Attribute_Descriptor } COSEM_Class_Id COSEM_Object_Instance_Id COSEM_Object_Attribute_Id Access_Selection_Parameters Access_Selector Access_Parameters | C M M M U M M | C (=) M (=) M (=) M (=) U (=) M (=) M (=) | – | – |
Block_Number | C | C (=) | – | – |
Response_Type | – | – | M | M (=) |
Result | – | – | M | M (=) |
Get_Data_Result { Get_Data_Result } Data Data_Access_Result | – | – | S S S | S (=) S (=) S (=) |
DataBlock_G Last_Block Block_Number Result Raw_Data Data_Access_Result | – | – | S M M M S S | S (=) M (=) M (=) M (=) S (=) S (=) |
同一个Response_Type可以出现多次,以显示对每种请求的可能响应。
COSEM_Attribute_Descriptor
参数引用COSEM对象属性。当Request_Type == NORMAL或WITH-LIST时出现(如果是 Request_Type=NEXT 就不用带 COSEM_Attribute_Descriptor
)。它是一个复合参数:
- (
COSEM_Class_Id
,COSEM_Object_Instance_Id
)双元明确引用一个且仅一个COSEM对象实例; COSEM_Object_Attribute_Id
元素标识对象实例的属性。COSEM_Object_Attribute_Id== 0
引用对象的所有公共属性(Attribute_0特性,参见9.1.4.3.7);Access_Selection_Parameters
仅在COSEM_Object_Attribute_Id!= 0
时存在,并且如果对给定属性的选择性访问可用;看到9.1.4.3.5。Access_Selector和Access_Parameters子参数在COSEM对象定义中定义,参见DLMS UA 1000-1。
GET-REQUEST-NORMAL服务原语包含一个COSEM属性描述符。GETREQUEST-WITH-LIST服务原语包含一个COSEM属性描述符列表;它们的数量受到server-max-receive-pdu-size。一个GET.request服务原语应始终适合于单个APDU。
Block_Number
参数在GET-REQUEST-NEXT
服务原语中使用。它携带正确接收到的最新数据块的编号。
- 如果响应的编码形式适合单个APDU,则Result的类型为
Get_Data_Result
:
Data
选项携带访问时属性的值;或Data_Access_Result
选项携带该属性读取失败的原因。
GET-RESPONSE-NORMAL
服务原语携带单个Get_Data_Result
参数。GET-RESPONSE-WITH-LIST
服务原语携带Get_Data_Result
参数列表;它们的数量和顺序应与请求中的COSEM_Attribute_Descriptor参数的数量和顺序相同。
如果COSEM_Object_Attribute_Id == 0 (Attribute_0),则数据应该是一个结构,包含所有公共属性的值,按照它们在给定对象规范中的出现顺序。对于在给定AA内未授予访问权限的属性,或者由于任何其他原因无法访问的属性,应返回空数据。
如果响应的编码形式不适合单个APDU,则可以使用特定于服务或通用块传输机制以数据块的形式传输响应。
如果使用基于服务的块传输机制,Result类型为DataBlock_G
。它携带块传输控制信息和原始数据;
Last_Block
元素指示当前块是否是最后一个块(TRUE)或不是(FALSE);
Block_Number
元素携带实际发送块的数量。
(内部)Result
元素携带Raw_Data
或Data_Access_Result
。在此:
如果请求单个属性的值,Raw_Data
会携带该属性值的一部分(Data);
当
Data
无法下发时,响应为GET-RESPONSE-NORMAL
,带Data_Access_Result
。
如果一个属性列表的值被请求,Raw_Data
携带Get_Data_Result-s
列表的一部分,每个属性的Data
或Data_Access_Result
;
如果原始数据无法交付,Data_Access_Result
将携带原因。错误情况请参见9.4.6.3。
- GET服务原语的可能逻辑序列如图87所示:
- 对于成功确认的GET,项a);
- 对于未确认的GET项d);和
- 由于本地错误项c)导致的失败尝试。
GET.request
原语由客户端AP调用,以读取服务器AP的一个或多个COSEM对象的一个或所有属性的值。第一个请求应始终为Request_Type ==NORMAL或WITH-LIST。一个GET-REQUEST-NEXT服务原语只有在服务器无法在单个响应中传递完整数据时才会被调用,即在接收到Response_Type == ONE-BLOCK的.confirm原语之后。在接收到.request原语之后,客户机AL构建适合该请求类型的Get-Request APDU,并将其发送到服务器。
GET.indication
原语由服务器AL在接收到Get-Request APDU时生成。
GET.response
原语由服务器AP调用,如果Service_Class == Confirmed,则向接收到的.indication原语发送响应。如果请求的完整数据适合单个APDU,则使用Response_Type == NORMAL或with-list调用.response原语。否则,用Response_Type == ONE-BLOCK调用它,最后用LAST-BLOCK调用它。
GET.confirm
原语由客户端AL生成,以指示接收到Get-Response APDU。
GET服务的协议在9.4.6.3中指定。
- SLF NOTE
- REQUEST-WITH-LIST 会带多个 COSEM_Attribute_Descriptor,但不能超过
server-max-receive- pdu-size。 - GET.request服务原语必须包含在单个APDU中,所以不能用分BLOCK方式发请求
- 整个
Response
单个APDU放得下就用Response_Type == NORMAL or WITH-LIST,放不下就用Response_Type == ONE-BLOCK ,最后一包用 LAST-BLOCK - COSEM_Object_Attribute_Id == 0 (Attribute_0 )的情况,表示读取所有的属性,返回一个包含所有数据的 结构体 ,填充在 Data区域,没权限的或访问出错的回null-data
- 关于 编解码,AP 层并不负责对 APDU 的编解码(比如 A-XDR编码),对于 AL 层原语的调用(如 COSEM-OPEN、GET等),传递的只是参数(或者叫变量),关于参数的格式和定义就是设计的问题了(可以使用编程语言的基本变量类型或自定义变量类型)。
- Table 60 中包含了原语的很多参数,但只有 部分 是需要被包含进 最终的APDU中的,所以 AP 编解码本身就解释不通,否则 AL需要再进行解码再封装,多此一举。其中 Result 中的 Data是一个octet-string格式 的参数,其内部的值已经是编完码的了,因为Data编解码是业务层蓝皮书的部分,需要AP来进行,但这里仅仅作为一octet-string 类型的变量,和AP不对整个APDU 进行编码的观点不冲突。AL属于绿皮书范畴,是通信的协议层,APDU是作为通信载体,应该属于绿皮书范畴,所以需要AL层编解码
9.3.7 The SET service
SET服务与LN referencing一起使用。它可以以已确认或未确认的方式调用。它的功能是写入一个或多个COSEM对象属性的值。要写入的数据可以在单个请求中发送,或者-如果太长而无法容纳单个请求-在多个请求中发送,使用块传输。服务原语的语义SET服务原语(不同于 GET,SET 请求可以分包)应提供如表54所示的参数。
.request | .indication | .response | .confirm | |
---|---|---|---|---|
Invoke_Id | M | M (=) | M (=) | M (=) |
Priority | M | M (=) | M (=) | M (=) |
Service_Class | M | M (=) | M (=) | M (=) |
Request_Type | M | M (=) | – | – |
COSEM_Attribute_Descriptor { COSEM_Attribute_Descriptor } COSEM_Class_Id COSEM_Object_Instance_Id COSEM_Object_Attribute_Id Access_Selection_Parameters Access_Selector Access_Parameters | C M M M U M M | C (=) M (=) M (=) M (=) U (=) M (=) M (=) | – | – |
Data {Data } | C | C (=) | – | – |
DataBlock_SA Last_Block Block_Number Raw_Data | C M M M | C(=) M(=) M(=) M(=) | – | – |
Response_Type | – | – | M | M (=) |
Result { Result } | – | – | C | C (=) |
Block_Number | – | – | C | C (=) |
For security parameters, see Table 50. |
Invoke_Id参数标识服务调用的实例。
Priority参数指示与服务调用实例相关联的优先级级别:正常(FALSE)或高(TRUE)。
Service_Class参数表示服务是否已确认。该参数的处理取决于通信配置文件。See 10。
Request_Type和Response_Type参数的使用如表55所示
Request type | Response type | ||
---|---|---|---|
NORMAL | The reference of a single attribute and the complete data to be written is sent. | NORMAL | The result is delivered. |
FIRST-BLOCK | 发送单个属性的引用和要写入的第一个数据块。 | ACK-BLOCK | 对正确接收的块进行确认。 |
ONE-BLOCK | 发送要写入的一个数据块。 | ||
LAST-BLOCK | 发送要写入的最后一块数据 | LAST-BLOCK | 最后一个块的正确接收被确认,结果被传递。 |
LAST-BLOCK- WITH-LIST | 最后一个块的正确接收被确认,结果列表被传递。 | ||
WITH-LIST | 发送属性列表的引用和要写入的完整数据。 | WITH-LIST | 结果列表被传递 |
FIRST-BLOCK-WITH- LIST | 发送属性列表的引用和要写入的第一个数据块。 | ACK-BLOCK | 对正确接收的块进行确认。 |
相同的Response_Type可能出现不止一次,以显示对每个请求的可能响应。 |
COSEM_Attribute_Descriptor
参数引用COSEM对象属性。当Request_Type == NORMAL、FIRST-BLOCK、WITH-LIST和FIRST-BLOCK-WITH-LIST时出现。它是一个复合参数:
- (COSEM_Class_Id, COSEM_Object_Instance_Id)双元明确引用一个且仅一个COSEM对象实例;
- COSEM_Object_Attribute_Id标识对象实例的属性。COSEM_Object_Attribute_Id == 0引用对象的所有公共属性(Attribute_0特性,参见9.1.4.3.7);
- Access_Selection_Parameters仅在COSEM_Object_Attribute_Id!=0时存在,并且如果对给定属性的选择性访问可用;看到9.1.4.3.5。Access_Selector和Access_Parameters子参数在COSEM对象定义中定义,参见DLMS UA 1000-1。
SET-REQUEST-NORMAL
或SET-REQUEST-WITH-FIRST-BLOCK
服务原语包含单个COSEM属性描述符。SET-REQUEST-WITH-LIST或SET-REQUEST-FIRSTBLOCK-WITH-LIST服务原语包含COSEM属性描述符列表;它们的数量受到server-max-receive-pdu-size的限制:所有COSEM属性描述符-连同要写入的数据的一部分-应该适合于单个APDU。
Data参数包含写入引用的属性值所需的数据。Data参数的数量和顺序应与COSEM_Attribute_Descriptor
参数的数量和顺序相同。
如果COSEM_Object_Attribute_Id== 0(Attribute_0),则发送的数据应该是一个结构,对于每个公共属性,按照它们在给定对象规范中的出现顺序,包含一个值或空数据,这意味着不需要设置给定属性。
如果Data参数的编码形式不适合单个APDU,则可以使用特定于服务的或通用的块传输机制以块的形式传输它。
- 如果使用特定于服务的块传输机制,则
DataBlock_SA参数
携带块传输控制信息和原始数据:
- Last_Block元素指示当前块是否是最后一个块(TRUE)或不是(FALSE);
- Block_Number元素携带实际发送块的数量;
- Raw_Data元素携带要写入的数据的一部分。
当Response_Type = ACK-BLOCK
时,Result参数出现在.response原语中。
它们的数量和顺序应与请求中的COSEM_Attribute_Descriptor参数的数量和顺序相同。每个Result应该包含写入成功或写入引用的属性失败的原因(Data_Access_Result)。当在.request原语COSEM_Object_Attribute_Id == 0 (Attribute_0)中时,Result应该为每个公共属性携带一个结果列表,按照它们在给定对象规范中的出现顺序,要么是写入成功,要么是写入失败的原因(Data_Access_Result)。
当Response_Type == ACK-BLOCK, LASTBLOCK或LAST-BLOCK-WITH-LIST
时,Block_Number
参数必须出现。它携带正确接收到的最新数据块的编号。
- SET服务原语可能的逻辑序列如图87所示:
- 对于成功确认的SET,第a项);
- 对于未确认的SET,请执行d)项;和
- 由于本地错误导致的失败尝试,参见c)项。
SET.request原语由客户端AP调用,用来写入服务器AP的一个或多个COSEM对象的一个或所有属性的值。如果要发送的完整数据适合单个APDU,则应使用Request_Type == NORMAL
或with-list
调用。否则,应使用Request_Type == FIRST-BLOCK
或FIRST-BLOCKWITH-LIST
调用它,然后使用Request_Type == ONE-BLOCK
,最后根据情况使用LAST-BLOCK
。在接收到.request原语之后,客户机AL构建适合于Request_Type的Set-Request
APDU,并将其发送到服务器。
SET.indication
原语由服务器AL在接收Set-Request APDU时生成。
SET.response
原语由服务器AP调用,如果Service_Class == Confirmed,则向接收到的.indication原语发送响应。
如果数据是在单个APDU中发送的,则使用Response_Type == NORMAL或with - list调用.response原语。
否则,使用Response_Type == ACK-BLOCK调用它,最后根据需要使用LAST-BLOCK或LAST-BLOCK- withlist调用它。
SET.confirm
原语由客户端AL生成,以指示接收Set-Response APDU。SET服务的协议在9.4.6.4中指定。
9.3.8 The ACTION service
ACTION服务与LN referencing一起使用。它可以以已确认或未确认的方式调用。它的功能是调用一个或多个COSEM对象方法。它包括两个阶段:
- 在第一阶段,客户端发送要调用的方法的引用,以及必要的方法调用参数;
- 在第二阶段,在调用方法之后,服务器回复调用方法生成的结果和返回参数(如果有的话)。
如果方法调用参数太长,无法在单个请求中容纳,那么它们将在多个请求中发送(从客户机到服务器的块传输)。如果结果和返回参数太长,无法在单个响应中容纳,则在多个响应中返回它们(从服务器到客户机的块传输)。
ACTION服务原语应提供如表56所示的参数。
.request | .indication | .response | .confirm | |
---|---|---|---|---|
Invoke_Id | M | M (=) | M (=) | M (=) |
Priority | M | M (=) | M (=) | M (=) |
Service_Class | M | M (=) | M (=) | M (=) |
Request_Type | M | M (=) | – | – |
COSEM_Method_Descriptor { COSEM_Method_Descriptor } COSEM_Class_Id COSEM_Object_Instance_Id COSEM_Object_Method_Id | C M M M | U(=) M(=) M(=) M(=) | – | – |
Method_Invocation_Parameters { Method_Invocation_Parameters } | U | U (=) | – | – |
Response_Type | – | – | M | M (=) |
Action_Response { Action_Response } Result Response_Parameters Data Data_Access_Result | – | – | M M U S S | M(=) M(=) U(=) S(=) S(=) |
DataBlock_SA Last_Block Block_Number Raw_Data | C M M M | C(=) M(=) M(=) M(=) | C M M M | C(=) M(=) M(=) M(=) |
Block_Number | – | – | C | C (=) |
For security parameters, see Table 50. |
Invoke_Id
参数标识服务调用的实例。
Priority
参数指示与服务调用实例相关联的优先级级别:正常(FALSE)或高(TRUE)。
Service_Class
参数表示服务是否已确认。该参数的处理取决于通信配置文件。看到10。
Request_Type
和Response_Type
参数的使用如表57所示。
Request type | Response type | ||
---|---|---|---|
NORMAL | 发送单个方法的引用和完整的方法调用参数。 | NORMAL | 发送结果和完整的返回参数 |
ONE-BLOCK | 发送结果和返回参数的一个块。 | ||
NEXT | 请求下一个数据块。 | ONE-BLOCK | As above. |
LAST-BLOCK | 发送结果和返回参数的最后一个块。 | ||
FIRST-BLOCK | 发送单个方法的引用和方法调用参数的第一个块。 | NEXT | 对正确接收的块进行确认。 |
ONE-BLOCK | 发送方法调用参数的一个块。 | ||
LAST-BLOCK | 发送方法调用参数的最后一个块。 | NORMAL | As above. |
ONE-BLOCK | As above. | ||
WITH-LIST | 发送方法列表的引用和方法调用参数的完整列表。 | WITH-LIST | 发送完整的结果列表和返回参数。 |
ONE-BLOCK | See above. | ||
WITH-LIST- AND-FIRST- BLOCK | 发送方法列表的引用和方法调用参数的第一个块。 | NEXT | 对正确接收的块进行确认。 |
COSEM-ABORT服务的功能是指示支持层的非请求断开。
服务原语的语义
COSEM-ABORT服务原语应提供如表48所示的参数。
Diagnostics
为可选参数。它应该表明断开连接的可能原因,也可以携带依赖于较低协议层的信息。该参数内容的说明不在本技术报告的范围内。
COSEM-ABORT.indication原语是在客户端和服务器端本地生成的,用于向COSEM AP指示较低层连接以非请求的方式关闭。当支持层连接不受DLMS/COSEM AL管理时,此类事件的起源可以是外部事件(例如物理线路中断),也可以是某些配置文件中存在的支持层连接管理器AP的动作。这将导致COSEM AP中止任何现有的AAs,除了服务器端预先建立的AAs。
COSEM-ABORT服务的协议在9.4.5.3中指定。
COSEM_Method_Descriptor
参数引用一个COSEM对象方法。它存在于Request_Type == NORMAL
,FIRST-BLOCK
,WITH-LIST
和WITH-LIST-AND-FIRST-BLOCK
。它是一个复合参数:
- (COSEM_Class_Id, COSEM_Object_Instance_Id)双元明确引用一个且仅一个COSEM对象实例;
- COSEM_Method_Id标识COSEM对象引用的一个方法。
ACTION-REQUEST-NORMAL
或ACTION-REQUEST-FIRST-BLOCK
服务原语应该包含一个COSEM方法描述符。ACTION-REQUEST-WITH-LIST
或ACTIONREQUEST-WITH-LIST-AND-FIRST-BLOCK
服务原语应包含COSEM方法描述符列表;它们的数量受到server-max-receive-pdu-size的限制:所有COSEM方法引用连同方法调用参数的一部分都应适合于单个APDU。
Method_Invocation_Parameter
参数携带了调用所引用的方法所必需的参数。
- 如果
Request_Type == NORMAL
, Method_Invocation_Parameter参数是可选的; - 如果
Request_Type == WITH-LIST
,服务原语应该包含Method_Invocation_Parameters列表。方法调用参数的数量和顺序应与COSEM_Method_Descriptor-s
相同。如果任何方法的调用不需要额外的参数,那么它仍然应该存在,但是它应该是空数据。
如果COSEM方法描述符和方法调用参数的编码形式不适合单个APDU,则可以使用特定于服务或通用块传输机制以块形式传输。
- 如果使用特定于服务的块传输机制,则
DataBlock_SA
参数携带块传输控制信息和原始数据:
Last_Block
元素指示当前块是否是最后一个块(TRUE)或不是(FALSE);Block_Number
元素携带实际发送块的数量;Raw_Data
元素携带部分方法调用参数。
- 当
Response_Type ==NORMAL
或WITH-LIST
时,Action_Response
参数出现在.response原语中。它们的数量和顺序应与COSEM方法描述符的数量和顺序相同。它由两个要素组成:
Result
参数。它包含要调用的成功或调用引用的方法失败的原因(Action-Result);Response_Parameter(s)
每个响应参数应该包含作为调用方法的结果返回的数据,或者返回参数失败的原因(Data- accessresult)。如果调用任何方法都没有返回参数,则将返回空数据。
如果响应不适合单个APDU,则可以使用特定于服务的块传输机制或通用块传输机制以块形式传输。
- 如果使用特定于服务的块传输机制,则
DataBlock_SA
参数携带块传输控制信息和原始数据:
Last_Block
元素指示当前块是否是最后一个块(TRUE)或不是(FALSE);- Block_Number元素携带实际发送块的数量;
Raw_Data
元素携带响应的一部分:
如果单个方法被调用,
Raw_Data
将携带结果和Response_Parameters
(如果有);如果不返回
Response_Parameters
,则响应类型为ACTION-RESPONSENORMAL
如果一个方法列表被调用,
Raw_Data
携带Action_Response-s
列表和可选数据的一部分。
ACTION-REQUEST-NEXT
服务原语中的Block_Number
参数应该正确携带从服务器接收到的最新数据块的数量。
ACTION-RESPONSE-NEXT
服务原语中的Block_Number
参数应该携带正确地从客户端接收到的最新数据块的编号。
- ACTION服务原语可能的逻辑序列如图87所示:
- 对于成功确认的ACTION, a)项;
- 对于未确认的ACTION项目d);和
- 由于本地错误项c)导致的失败尝试。
在第一阶段,ACTION.request原语由客户机AP调用,以调用服务器AP的一个或多个COSEM对象的一个或多个方法。如果COSEM方法描述符和方法调用参数的完整列表适合单个APDU,则使用Request_Type == NORMAL
或with-list
适当地调用.request原语。否则,将酌情使用Request_Type == FIRST-BLOCK
或with-list-and-FIRST-BLOCK
调用它,然后使用Request_Type == ONE-BLOCK
,最后使用LAST-BLOCK
。在接收到.request原语之后,客户机AL构建适合于Request_Type的Action-Request APDU
,并将其发送到服务器。
ACTION.indication
原语由服务器AL在接收到ActionRequest APDU时生成。
在方法调用参数的块传输过程中,服务器AP调用ACTION。使用Request_Type == NEXT
返回响应原语,直到接收到最后一个块。
ACTION.confirm
原语是由客户端接收到ActionResponse APDU后生成的。
一旦转移了所有方法调用参数,服务器就调用所引用的COSEM对象的方法,然后开始第二阶段。
如果完整的响应适合单个APDU,则ACTION。响应原语由服务器AP根据需要使用Response_Type == NORMAL
或with - list
调用。否则,用Response_Type == ONE-BLOCK
调用它,最后用LAST-BLOCK
调用它。在接收到.response原语之后,服务器AL构建适合Response_Type
的Action-Response APDU
,并将其发送给客户端。
ACTION.confirm
原语由客户端AL生成,以指示接收ActionResponse APDU。
在返回参数的块传输期间,客户机AP使用Request_Type == NEXT
调用.request原语,直到接收到最后一个块。
ACTION服务的协议在9.4.6.5中指定。
- SLF NOTE
- 请求响应都能分包,需要请求 完整发完 ,响应才开始分包发送结果
- 第一阶段 :client AP向AL 发送ACTION.request,server 的AL收到后向AP发送ACTION.indication,server AP回 ACTION.response,ACTION.confirm.由AL发送给clientAP,都是可以是分包的。直到收到完整的请求(LAST-BLOCK 发送后)。
- 第二阶段 :开始执行方法,执行完后返回结果,可以分包
9.3.9 The ACCESS service
9.3.9.1 Overview – Main features
9.3.9.1.1 General
ACCESS服务是一个统一的服务,可以使用一个.request / .response访问多个COSEM对象属性和/或方法。引入它的目的是改进xDLMS消息传递,同时保持与现有xDLMS服务的共存。
9.3.9.1.2 Unified WITH-LIST service to improve efficiency
统一WITH-LIST服务,提高效率
ACCESS服务是使用LN referencing
的统一服务,可用于读写多个COSEM对象属性和/或使用单个.request/ .response调用多个方法。每个请求都包含一个请求列表和相关数据。每个响应包含一个返回数据列表和请求的结果。
目前不支持
LN referencing
。它可以通过引入服务的新变体来添加。
GET/SET/ACTION-WITH-LIST服务请求只能在列表中包含一种请求类型——GET、SET和/或ACTION,而ACCESS服务请求可以包含不同的请求类型。这可以减少交换的数量,从而提高效率。
请求列表的处理从列表上的第一个请求开始,并继续处理下一个请求,直到到达末尾。
9.3.9.1.3 Specific variants for selective access
用于选择性访问的特定变体
GET/SET.request
服务原语应始终包含Access_Selection_Parameters
,即使在没有选择性访问或不需要选择性访问的情况下也是如此。与此相反,ACCESS服务提供了访问属性的特定变体,可以不进行或具有选择性访问。当选择性访问不可用或不需要时,这避免了包含Access_Selection_Parameters
的需要,从而减少了开销并提高了效率。
9.3.9.1.4 Long_Invoke_Id parameter
GET、SET和ACTION服务的Invoke-Id参数允许客户端和服务器将请求和响应配对。Invoke_Id
的取值范围是0 ~ 15。
在某些情况下,这是不够的。为了支持这些情况,ACCESS服务使用Long_Invoke_Id
参数。Long_Invoke_Id
的取值范围是0…16 777 215
。
对于长Invoke_id-s有用的情况的描述超出了本技术报告的范围
9.3.9.1.5 Self-descriptive responses
当客户端请求时,ACCESS.response
服务原语不仅携带对每个请求的响应(即访问每个属性/方法的结果和返回数据),而且还携带Access_Request_Specification服务
参数(携带属性/方法引用)和Access_Selection
参数(呈现描述自.response服务的原语)。这种自作者描述的响应可以自己存储和处理,而不需要将响应和请求配对。
SLF NOTE
不仅包含结果data,也包含请求参数,可以不依赖于对应的请求直接解析响应
9.3.9.1.6 Failure management
在GET-/SET-/ACTION-WITH-LIST服务的情况下,如果其中一个请求失败,客户端无法控制应该发生什么。相反,ACCESS服务允许客户端控制列表中失败请求之后的请求是否应该处理。
9.3.9.1.7 Time stamp as a service parameter
前面指定的xDLMS服务没有在.request或.response服务原语中提供服务参数来携带时间戳。
相反,ACCESS服务原语提供了一个服务参数来携带时间戳,该时间戳包含调用服务原语的日期和时间。这反而减少了开销。
9.3.9.1.8 Presence of data in service primitives
服务原语中数据的呈现
- 关于服务原语中的数据GET/SET/ACTION服务和ACCESS服务之间有重要的区别:
- GET服务:请求中没有数据。在响应中,返回数据或结果(Data-Access-Result);
- SET服务:数据存在于请求中。在响应中,只返回结果(Data-Access-Result);
- ACTION服务:请求中的方法调用参数是可选的。在响应中,将返回调用方法(Action-Result)的结果和返回返回参数(Data或Data-Access-Result)的可选结果;
- ACCESS服务:数据与请求中的每个属性/方法引用相关联。如果特定请求不需要数据,则包含空数据。在响应中,将同时返回数据和结果。如果没有要为特定响应返回的数据,则包含空数据。在访问方法的情况下,Access-Response-Action (Action-Result)传递调用方法的结果和返回返回参数的结果。
9.3.9.2 Service specification
ACCESS服务是使用LN referencing的统一服务,可用于读写多个COSEM对象属性和/或使用单个.request/ .response调用多个方法。每个请求都包含一个请求列表和相关数据。每个响应包含一个返回数据列表和请求的结果。它可以以已确认或未确认的方式调用。
它可以与一般的块传输和一般的加密机制一起使用。
- 一致性块的使用如下:
- bit17 访问表示支持ACCESS服务;
- bit 1
general-protection
表示通用保护apdu的可用性; - bit 2
general-block-transfer
表示GBT机制的可用性; - bit 8
attribute0-supported-with-set
和bit 10attribute0-supported-with-get
(10)不相关:总是支持attribute0; - bit 9
优先级管理支持(priority-mgmt-supported)
是相关的; - bit 14
多引用(multiple-references)
是不相关的:ACCESS服务总是支持多引用; - bit 21
选择性访问(selective-access)
是相关的。只有成功协商了选择访问的使用,才能使用访问选择参数。
服务原语的语义
ACCESS服务原语应提供如表58所示的参数。
Long_Invoke_Id
、Self_Descriptive
、Processing_Option
、Service_Class
和Priority
为必选参数。它们在.indication, .response 和.confirm服务原语中的值应与.request服务原语中的值相同。它们由访问请求/访问响应APDU的long-invoke-id和priority字段的bit携带:
- long-invoke-id(bit0-23)标识服务调用的实例;
self-descriptive
(bit 28)表示服务响应是不自描述的(FALSE)还是自描述的(TRUE)。当设置为TRUE时,Access_Response_Body
参数应包含Access_Request_Specification
参数;
Access_Request_List_Of_Data参数不包含在.response服务原语中。
processing-option
(bit 29)指定当处理列表上的请求失败时要做什么。当设置为FALSE时,继续处理。当设置为TRUE时,处理中断,即列表中跟随失败请求的请求将不被处理。如9.3.9.1.2所述,对请求列表的处理应从列表上的第一个请求开始,并继续处理下一个请求,直至到达列表末尾;service-class
(bit 30)指示服务调用是确认(TRUE)还是未确认(FALSE);
Service_Class
参数适用于服务调用,而不是列表中的单个请求。
根据通信配置文件的不同,Service_Class
参数也可以决定用于携带APDU的帧类型。
priority
(bit 31)表示与服务调用实例关联的优先级级别。它可能是正常(FALSE)或高(TRUE)。
Priority
参数适用于服务调用,而不是列表中的单个请求。
Date_Time服务为可选参数。当出现时,它应包含服务.request /.response调用的日期和时间。由访问请求/访问响应APDU的OCTET STRING类型的date-time字段携带。当不存在时,OCTET字符串的长度为0。除非项目特定的配套规范中另有规定,如果请求中有Date_Time参数,则响应中的Date_Time参数应出现;如果请求中没有Date_Time参数,则响应中不应出现该参数。
.request | .indication | .response | .confirm | ||
---|---|---|---|---|---|
Long_Invoke_Id | M | M (=) | M (=) | M (=) | |
Self_Descriptive | M | M (=) | M (=) | M (=) | |
Processing_Option | M | M (=) | M (=) | M (=) | |
Service_Class | M | M (=) | M (=) | M (=) | |
Priority | M | M (=) | M (=) | M (=) | |
Date_Time | U | U (=) | U | U (=) | |
Access_Request_Body Access_Request_Specification { Access_Request_Specification } Access_Request_Get COSEM_Attribute_Descriptor Access_Request_Set COSEM_Attribute_Descriptor Access_Request_Action COSEM_Method_Descriptor Access_Request_Get_With_Selection COSEM_Attribute_Descriptor Access_Selection Access_Selector Access_Parameters Access_Request_Set_With_Selection COSEM_Attribute_Descriptor Access_Selection Access_Selector Access_Parameters Access_Request_List_Of_Data Data { Data } | M M U M U M U M U M M M M U M M M M M | M (=) M (=) U (=) M (=) U (=) M (=) U (=) M (=) U (=) M (=) M (=) M (=) M (=) U (=) M (=) M (=) M (=) M (=) M (=) | – | – | |
Access_Response_Body Access_Request_Specification { Access_Request_Specification } Access_Response_List_Of_Data Data{ Data } Access_Response_Specification { Access_Response_Specification} Access_Response_Get Result Access_Response_Set Result Access_Response_Action Result | – | – | M C (=)1 M M C M C M C M | M (=) C (=) M (=) M (=) C (=) M (=) C (=) M (=) C (=) M (=) | |
1当Access_Request_Specification服务参数存在于Access_Response_Body中时,其值应与.Request/.indication原语中的值相同。 |
如果对属性的选择性访问不可用,或者COSEM_Attribute_Descriptor标识了所有属性(Attribute_0),则不应使用Access_Request_Get_ /Set_ With_Selection
.
- SLF NOTE
不能用于 Attribute_0
COSEM_Attribute_Descriptor
参数是一个复合参数:
- (COSEM_Class_Id, COSEM_Object_Instance_Id)双元明确引用一个且仅一个COSEM对象实例;
- COSEM_Object_Attribute_Id元素标识对象实例的属性。COSEM_Object_Attribute_Id == 0引用对象的所有公共属性。
Access_Selection
参数携带Access_Selector
和Access_Parameters
子参数。可能的值在相关的COSEM接口类定义中定义。
Access_Request_List_Of_Data
参数携带与Access_Request_Specification参
数列表相关的数据列表。数据取决于访问请求的类型:
Access_Request_Get
引用一个或所有属性(Attribute_0): null-data;Access_Request_Set
:对应的数据携带要写入的值。在引用所有属性(Attribute_0)的情况下,数据应该是一个结构。结构中元素的数量应与相关COSEM IC规范中规定的属性数量相同。结构中的每个元素都包含要写入的值或空数据,这意味着不需要写入给定的属性;Access_Request_Action
:相应的数据携带方法调用参数,如果不需要则为空数据。
两份表中元素的数量和顺序应当相同。
Access_Response_Body
参数包含以下子参数:
Access_Request_Specification
(可选,仅当Self_Descriptive == TRUE
时);Access_Response_List_Of_Data
;和Access_Response_Specification
注意,在响应中,Access_Request_List_Of_Data
首先出现,然后是Access_Response_Specification
。如果提供了数据,但结果表明失败,那么客户端应该丢弃数据。
- SLF NOTE
- 优先判断 result,如果 result 失败直接丢弃 data。
Access_Request_Specification
参数出现时,应该与.request/ .indication原语中的参数相同。
Access_Response_List_Of_Data
参数携带处理请求产生的数据。列表中的元素数量应与Access_Request_Specification
列表中的元素数量相同。数据取决于访问请求的类型:
Access_Request_Get
引用单个属性:被请求的属性的值,或者当属性的值不能返回时为null-data;Access_Request_Get
引用所有属性(Attribute_0): data应该是一个结构,包含每个属性的值。结构中元素的数量应与相关COSEM IC规范中规定的属性数量相同。如果不能返回某个属性的值,则该属性应包含空数据。如果不能返回任何属性值,则返回一个null-data;Access_Request_Set
引用一个或所有属性(Attribute_0): null-data;Access_Request_Action
:返回参数,如果没有提供,则返回null-data。
Access_Response_Specification
参数携带每个请求的结果。此列表中的元素数量应与Access_Request_Specification
列表中相同:
Access_Request_Get
引用单个属性:读取属性的结果:成功或失败的原因;Access_Request_Get
引用所有属性(Attribute_0):如果可以返回被授予访问权限的所有属性的值,则结果为成功。否则,它将是数据访问-给出失败原因的结果;Access_Request_Set
引用单个属性:写入属性的结果:成功或失败的原因;Access_Request_Set
引用所有属性(Attribute_0):如果授予访问权限的所有属性的值都可以写入,则结果为成功。否则,它将是数据访问-给出失败原因的结果;Access_Response_Action
携带调用方法的结果:成功或失败的原因。
如果方法能够被成功调用,并且当IC规范指定返回参数时,它们能够被成功返回,则结果应为成功。
否则,应是Action-Result
给出失败的原因。
如果Processing_Option
参数设置为TRUE,并且处理列表中的请求失败,那么对于失败的请求之后的所有请求,Access_Response_List_Of_Data
应该包含null-data
,
Access_Response_Specification
应该包含失败的原因。
- ACCESS服务原语可能的逻辑序列如图87所示:
- 对于成功确认的ACCESS,a项);
- 对于未确认的ACCESS,d项);和
- 由于本地错误项c)导致的失败尝试。
ACCESS.request
原语由客户机AP调用,以读取或写入COSEM对象属性列表的值和/或调用方法列表。
ACCESS.indication
原语由服务器AL在接收到AccessRequest APDU时生成。
ACCESS.response
原语由服务器AP调用(如果Service_Class == Confirmed),以向接收到的.指示原语发送响应。
ACCESS.confirm
原语由客户端AL生成,以指示接收到access-response APDU。
当请求或响应不适合单个APDU时,可以使用通用块传输机制。看到9.1.4.4.9。
如果响应太长而无法装入单个APDU,但不支持GBT,则响应可能是空数据列表和指示失败原因的结果列表。
当需要加密保护时,根据要应用的保护类型,访问请求/访问响应apdu可以在general-ded-ciphering, general-glo-ciphering, general-ciphering or general-signing
中传输。看到9.3.5
ACCESS服务的协议在9.4.6.6中指定。
9.3.10 The DataNotification service
DataNotification
服务是未经请求、未经确认的服务。服务器使用它将数据推送到客户端。这是一项未经证实的服务。推送过程通过"Push setup"对象进行配置;参见DLMS UA 1000-1 Ed. 12.2: 2017,4.4.8。
DataNotification服务原语应提供如表59所示的参数
.request | .indication | |
---|---|---|
Long_Invoke_Id | M | M (=) |
Self_Descriptive | – | – |
Processing_Option | – | – |
Service_Class | – | – |
Priority | M | M (=) |
Date_Time | U | U (=) |
Notification_Body | M | M (=) |
Long_Invoke_Id
参数标识服务调用的实例。参见9.3.9。
Self_Descriptive
、Processing_Option
和Service_Class
参数在此服务中不使用。
Priority
参数指示与服务调用实例相关联的优先级级别:正常(FALSE)或高(TRUE)。
可选参数Date_Time
表示在DataNotification.request调用时发生的时间
Notification_Body
参数包含推送数据。
如果请求的编码形式不适合单个APDU,则可以使用general block transfer
以数据块的形式传输请求。
DataNotification
服务原语的可能逻辑序列如图87 (f)和(g)所示。
服务器AP调用.request原语,将数据推送到远程客户端AP。在接收到.request原语后,服务器AL构建DataNotification
APDU。
DataNotification.indication
原语由客户端AL在接收到DataNotification APDU
后生成。
DataNotification
服务的协议在9.4.6.7中指定。
9.3.11 The EventNotification service
EventNotification
服务是一种未经请求的服务,在事件发生时由服务器发起,目的是通知客户端一个属性的值,就像COSEM请求它一样。这是一项未经证实的服务。
- SLF NOTE
- 无需确认request
EventNotification
服务原语应该提供如表60所示的参数。
.request | .indication | |
Time | U | U (=) |
Application_Addresses | U | U (=) |
COSEM_Attribute_Descriptor COSEM_Class_Id COSEM_Object_Instance_Id COSEM_Object_Attribute_Id | M M M M | M (=) M (=) M (=) M (=) |
Attribute_Value | M | M (=) |
可选参数Time
表示发出EventNotification.request
服务原语发生的时间
。
Application_Addresses
是可选参数。只有在已建立的AA之外调用EventNotification服务时才会出现。在这种情况下,它包含识别发送端和目的端APs所需的所有协议特定参数。
- SLF NOTE
- 如果没有相应的AA,则包含全部识别信息(也就是允许没有AA的情况上报)
当 .request
原语不包含可选的Application_Addresses
参数时,默认地址应使用,服务器管理逻辑设备和客户端管理AP的地址应使用。这两个APs总是存在,并且在任何协议配置文件中,它们被绑定到已知的预定义地址。
(COSEM_Class_Id
, COSEM_Object_Instance_Id
, COSEM_Object_Attribute_Id
)三元组明确地引用COSEM对象实例的一个且只有一个
属性。
Attribute_Value
参数携带该属性的值。可以通过查询这个COSEM对象获得关于通知事件的更多信息。
如果请求的编码形式不适合单个APDU,则可以使用general block transfer
以数据块的形式传输请求。
EventNotification
服务原语的可能逻辑序列如图87 (f)和(g)所示。
服务器AP调用.request原语,将COSEM对象属性的值发送给远程客户端AP。在接收到.request原语后,服务器AL构建事件通知请求APDU。
在某些情况下,支持层协议不允许以真实的、未经请求的方式发送协议数据单元。在这些情况下,客户端必须通过调用TriggerEventNotificationSending
服务原语显式请求发送EventNotification
帧。
EventNotification.indication
原语是由客户机AL在接收到事件通知请求APDU时生成的。
EventNotification服务的协议在9.4.6.8中指定。
9.3.12 The TriggerEventNotificationSending service
TriggerEventNotificationSending
服务的功能是通过客户端触发服务器发送携带EventNotification.request APDU的帧。
当服务器无法发送真正的non-solicited EventNotification.request APDU时,该服务是必要的。
TriggerEventNotificationSending.request
服务原语应提供如表61所示的参数。
.request | |
Protocol_Parameters | M |
Protocol_Parameters参数包含所有低层协议层相关信息,这是触发服务器发送包含EventNotification.request 的APDU。该信息包括协议标识符和所有所需的底层参数。
当收到TriggerEventNotificationSending事件时。当客户端AP请求服务调用时,客户端AL应调用相应的支持层服务向服务器发送触发消息。
- SLF NOTE
- EventNotification的触发服务,由客户端发起,用于EventNotification不能自动触发的情况,不需要建立AA
9.3.13 Variable access specification
Variable_Access_Specification
是Read / Write / UnconfirmedWrite
InformationReport .request / .indication service原语的一个参数。
- 其变体如表62所示:
-
Variable_Name
标识DLMS命名变量; -
Parameterized_Access
提供传输额外参数的能力; -
Block_Number_Access
传输一个块号; -
Read_Data_Block_Access
传输块传输控制信息和原始数据; -
Write_Data_Block_Access
传输块传输控制信息。
不同变体的使用取决于服务,并在各自的SN服务规范中进行了描述。
Variable_Access_Specification | Read.request | Write.request | Unconfirmed Write.request | Information Report |
---|---|---|---|---|
Kind_Of_Access | M | M | M | M |
Variable_Name | S | S | S | M |
Detailed_Access | Not used in DLMS/COSEM | |||
Parameterized_Access Variable_Name Selector Parameter | S M U U | S M U U | S M U U | – |
Block_Number_Access Block_Number | S M | – | – | – |
Read_Data_Block_Access Last_Block Block_Number Raw_Data | S M M M | – | – | – |
Write_Data_Block_Access Last_Block Block_Number | – | S M M | – | – |
9.3.14 The Read service
Read服务与SN referencing一起使用。它是confirmed服务。
- 它的功能是:
-
读取一个或多个COSEM对象属性的值。在这种情况下,.request服务原语的编码形式应该适合于单个APDU。结果可以在单个响应中交付,或者-如果太长而无法容纳单个响应-使用块传输在多个响应中交付;
-
当期望返回参数时,调用一个或多个COSEM对象方法。在这种情况下,如果.request(包括方法引用和方法调用参数)或.response服务原语(包括结果和返回参数)太长而无法容纳在单个APDU中,则可以使用带有多个请求和/或响应的块传输。
Read服务原语应提供如表63所示的服务参数。
读取服务在IEC 61334-4- 41:20 96 10.4和附录a中进行了规定。为了完整性和与使用LN referencing的服务规范的一致性,此处复制了该规范,以及为DLMS/COSEM所做的扩展。
.request | .indication | .response | .confirm | |
---|---|---|---|---|
Variable_Access_Specification { Variable_Access_Specification } Variable_Name Parameterized_Access Variable_Name Selector Parameter | M S S M U U | M(=) S(=) S(=) M(=) U(=) U(=) | - | - |
Read_Data_Block_Access Last_Block Block_Number Raw_Data | S M M M | S(=) M(=) M(=) M(=) | ||
Block_Number_Access Block_Number | S M | S (=) M (=) | ||
Result (+) | S | S (=) | ||
Read_Result { Read_Result } | – | – | M | M (=) |
Data Data_Access_Error | S S | S (=) S (=) | ||
Data_Block_Result Last_Block Block_Number Raw_Data Block_Number | S M M M S | S (=) M (=) M (=) M (=) S (=) | ||
Result (–) Error_Type | – | – | S M | S (=) M (=) |
安全参数请参见9.3.5。 |
使用Read.request服务原语和不同选择Read.response原语
的Variable-Access-Specification服务参数的不同变体,原语如表64所示。
如果响应的编码形式不适合单个APDU,则可以使用general block transfer
以数据块的形式传输。
Read.request Variable_Access_Specification | Read.response CHOICE | ||
---|---|---|---|
变量名 {Variable_Name} | 引用COSEM对象属性的列表1 | Data {Data} | 传递引用的属性的值。 |
Data_Access_Error{Data_Access_Error} | 提供读取失败的原因。 | ||
Data_Block_Result | 提供块传输控制信息和一个原始数据块。 | ||
参数化的访问{Parameterized_Access} | 引用要选择性读取的COSEM对象属性列表1。 | Data {Data} | As above. |
Data_Access_Error{Data_Access_Error} | |||
Data_Block_Result | |||
引用带有方法调用参数的COSEM对象方法列表1 | Data {Data} | 传递方法调用返回参数。如果返回参数,则意味着方法调用成功 | |
Data_Access_Error{Data_Access_Error} | 提供方法调用失败的原因。 | ||
Data_Block_Result | As above. | ||
Read_Data_Block_ Access | 携带块传输控制信息和COSEM方法引用和方法调用参数的一部分编码形式。 | Block_Number | 携带最新接收到的数据块的编号。 |
Block_Number_Access | 携带最新接收到的数据块的编号。 | Data_Block_Result | As above. |
NOTE :同样的Read.response选择可能出现不止一次,以显示对每个请求的可能响应。 1列表可以有一个或多个元素。 |
Read.request
服务原语可以有一个或多个Variable_Access_Specification
参数。
-
Variable_Name
变量用于引用要读取的完整COSEM对象属性。请求可能包含一个或多个变量名; -
- Parameterized_Access变量可以使用:
- 为了引用要选择性读取的COSEM对象属性。在这种情况下,
Variable_Name
元素引用COSEM object attribute
,Selector
和Parameter元素分别携带属性规范中指定的访问选择器和访问参数
;或 - 为了引用要调用的COSEM对象方法。在这种情况下,
Variable_Name
元素引用方法,Selector
元素为零,Parameter元素携带方法调用参数(如果有的话)或null data
; - 请求可能包括一个或多个参数化访问参数;
这样,Read服务可以在两个方向上传输信息,就像LN referencing的ACTION服务一样:从客户端到服务器引用方法调用参数,从服务器到客户端返回参数。
-
- 当调用一个或多个COSEM对象方法并且请求的编码形式不适合单个APDU时,使用
Read_Data_Block_Access
变体。请求可能包含一个Read_Data_Block_Access
参数。它携带块传输控制信息和原始数据:
Last_Block
元素指示给定的块是否是最后一个(TRUE)或不是(FALSE);Block_Number
元素携带实际发送块的数量;Raw_Data
元素携带Variable_Access_Specification
参数列表的一部分编码形式(因为它将在没有块传输的情况下使用),包括方法引用和方法调用参数。在这里,只允许变量Variable_Name
和Parameterized_Access
;Block_Number_Access
变量在服务器使用块传输发送长响应时使用,以确认接收数据块并请求下一个数据块。请求可能包含单个Block_Number_Access
参数。它携带正确接收到的最新数据块的编号。
- 当调用一个或多个COSEM对象方法并且请求的编码形式不适合单个APDU时,使用
-
Result(+)参数表示请求的服务成功。
-
如果没有块传输,
.response/.confirm
服务原语包含一个或多个Read_Result
参数。它们的数量和顺序应与.request/.indication原语中的Variable_Name/Parameterized_Access
参数的数量和顺序相同。 -
- 如果使用Read服务读取属性,则:
- 采用
Data选项
携带访问时属性的值; Data_Access_Error
用于携带该属性读取失败的原因。
-
- 如果使用Read服务来调用方法,则:
- 采用Data选项来携带返回参数(如果返回数据,这意味着方法调用成功)。如果没有返回参数,Data应该是空数据。
但是,如果期望没有返回数据,则应使用Write服务来调用方法。
- 采用
Data_Access_Error
选项来携带该方法调用失败的原因。
-
- 在块传输的情况下,.response /.confirm原语包含一个
Read_Result
参数。Data_Block_Result
选项被用来携带响应的一个块:
Last_Block
元素指示给定的块是否是最后一个(TRUE)或不是(FALSE);Block_Number
元素携带发送块的数量;Raw_Data
元素包含Read_Results
列表的一部分编码形式。
- 在块传输的情况下,.response /.confirm原语包含一个
-
如果不能提供数据块,则.response原语应使用
Data_Access_Error
选项携带单个Result参数,并携带适当的错误消息:例如(14)data-block-unavailable。 -
如果请求中的块号不是预期的那个,或者下一个块不能交付,则
Read.response
服务原语应返回一个Read_Result
参数,选择Data_Access_Error
,并携带适当的代码,例如(19)data-blocknumber-invalid。 -
当使用Read服务调用一个或多个方法并以几个块的形式发送请求时,将采用
Block_Number
选项,以确认正确接收数据块并请求下一个块。它携带了最近收到的区块的编号。 -
Result(-)参数表示先前请求的服务失败。
Error_Type
参数提供了失败的原因。在这种情况下,服务器应该返回一个confirmedServiceError APDU
,而不是一个ReadResponse APDU
。 -
Read服务原语的可能逻辑序列如图87中的A项所示。
-
Read.request原语是在客户端AP调用
GET或ACTION.request原语
并通过客户端SN_Mapper ASE映射原语
到Read.request原语。客户机AL然后构建readRequest APDU并将其发送到服务器。详情查看LN/SN service(9.4.6.9). -
Read.indication原语由服务器AL在接收到readRequest APDU时生成。
-
Read.response原语由服务器AP调用,以便向先前接收到的Read.indication发送响应。服务器AL然后构建readResponse APDU并发送它给客户。
-
Read.confirm原语是由客户端AL在接收到readResponse APDU后生成的。然后,它被Client SN_Mapper ASE映射回
GET或ACTION.confirm
原语,并生成GET或ACTION.confirm原语
。
Read服务的协议在9.4.6.9中指定。
9.3.15 The Write service
Write服务与SN referencing一起使用。它是确认服务。
- 它的功能是:
- 写入一个或多个COSEM对象属性的值;
- 当没有返回参数时调用一个或多个COSEM对象方法。
在这两种情况下,如果.request服务原语的编码形式不适合单个APDU,则可以使用块传输将其发送到多个请求中。response服务原语应始终适合于单个APDU。
写入服务在IEC 61334-4-41:1996 10.5和附录a中有规定。为了完整性和与使用LN referencing的服务规范的一致性,这里复制了该规范,以及为DLMS/COSEM所做的扩展。
Write服务原语应提供如表65所示的服务参数。
.request | .indication | .response | .confirm | |
---|---|---|---|---|
Variable_Access_Specification { Variable_Access_Specification } Variable_Name Parameterized_Access Variable_Name Selector Parameter | M S S M U U | M(=) S(=) S(=) M(=) U(=) U(=) | - | - |
Write_Data_Block_Access Last_Block Block_Number | S M M | S(=) M(=) M(=) | ||
Data { Data } | M | M(=) | ||
Result (+) | S | S (=) | ||
Write_Result { Write_Result } Success Data_Access_Error | S S S | S(=) S(=) S(=) | ||
Block_Number | S | S (=) | ||
Result (–) Error_Type | – | – | S M | S (=) M (=) |
安全参数请参见9.3.5。 |
使用Write的Variable-Access-Specification
服务参数的不同变体。请求服务原语和Write的不同选择。响应原语如表66所示。还解释了Data服务参数的使用。
如果请求的编码形式不适合单个APDU,则可以使用特定于服务或通用块传输机制以数据块的形式传输请求。
Write.request Variable_Access_Specification | Write.response CHOICE | ||
---|---|---|---|
Variable_Name{Variable_Name} | 引用COSEM对象属性的列表1。Data服务参数携带要写入的数据或方法调用参数。 | Success {Success} | 指示所引用的属性可以成功写入。. |
Data_Access_Error{Data_Access_Error} | Provides the reason for the write to fail. | ||
参数化的访问{Parameterized_Access} | 引用要选择性写入的COSEM对象属性列表1。"Data"服务参数携带要写入的数据。 | Success {Success} | As above. |
Data_Access_Error{Data_Access_Error} | |||
Write_Data_Block_Access | 携带块传输控制信息。Data服务参数携带原始数据,包括COSEM对象属性或方法引用列表1的编码形式,以及要写入的数据列表或方法调用参数列表。 | Block_Number | 携带最新接收到的数据块的编号。 |
NOTE同样的Write.response选择可能出现不止一次,以显示对每个请求的可能响应。 1列表可以有一个或多个元素。 |
- Write.request服务原语可以有一个或多个
Variable_Access_Specification
参数:
Variable_Name
变量用于引用要写入的完整COSEM对象属性或要调用的COSEM对象方法。请求可能包含一个或多个变量名;Parameterized_Access
变量用于引用要选择性写入的COSEM对象属性。在这种情况下,Variable_Name
元素引用COSEM对象属性,Selector和Parameter元素分别携带属性规范中指定的访问选择器和访问参数。请求可以包含一个或多个Parameterized_Access
参数。
Data服务参数携带要写入属性的值,或者要调用的方法的方法调用参数。Data参数的数量和顺序应与Variable_Access_Specification
参数的数量和顺序相同。
- 如果Write.request服务原语不适合单个APDU,可以使用块传输。在这种情况下:
-
Variable_Access_Specification
的Write_Data_Block_Access
变量携带块传输控制信息:
Last_Block
元素指示给定的块是否是最后一个(TRUE)或不是(FALSE);Block_Number
元素携带实际发送块的数量;
Data
参数携带属性引用列表和要写入的数据列表的一部分,或者方法引用列表和方法调用参数列表的一部分;请求
包含一个Write_Data_Block_Access
和一个Data参数。
Result(+)参数表示请求的服务成功。
.response / .confirm服务原语包含Write_Result参数列表。它们的数量和顺序应与.request / .indication服务原语中的Variable_Name/Parameterized_Access
参数的数量和顺序相同。
- 在不进行块传输的情况下,以及在接收到最后一个块之后进行块传输:
- 当Write服务用于写属性时,每个元素要么携带写访问的成功(success),要么携带写失败的原因(Data_Access_Error);
- 当Write服务用于调用方法时,每个元素要么携带方法调用访问的成功(success),要么携带方法调用失败的原因(Data_Access_Error)。
Block_Number选项在块传输期间用于确认正确接收数据块并请求下一个块。它携带了最近收到的区块的编号。
如果请求中的block-number不是预期的那个,或者如果块不能被正确接收,则Write.response服务原语应返回一个Write_Result参数,选择Data_Access_Error,并携带适当的代码,例如(19)datablock-number-invalid。
Result(-)参数表示请求的服务失败。Error_Type参数提供了失败的原因。在这种情况下,服务器应该返回一个confirmedServiceError APDU
,而不是writeResponse APDU
。
Write服务原语的可能逻辑序列如图87中的A项所示。
Write.request原语是在客户端AP调用SET或ACTION .request原语并将其映射到Write之后调用的。请求原语由客户端SN_Mapper ASE。客户机AL然后构建writeRequest APDU并将其发送到服务器。LN / SN业务映射请参见9.4.6.10。
Write.indication原语由服务器AL在接收到writerequestapdu时生成。
Write.response原语由服务器AP调用,以便向先前接收到的Write发送响应。显示原始。服务器AL然后构建writeResponse APDU并将其发送到客户机。
Write.confirm 原语是由客户机AL在接收到writeResponse APDU后生成的。然后,它被Client SN_Mapper ASE映射回SET或ACTION .confirm原语,并生成SET或ACTION .confirm原语。
Write服务的协议在9.4.6.10中指定
9.3.16 The UnconfirmedWrite service
- UnconfirmedWrite服务与SN referencing.一起使用。这是一项未经确认的服务。其功能是:
- 写入一个或多个COSEM对象属性的值;
- 在不期望返回参数时调用一个或多个COSEM对象方法。UnconfirmedWrite.request服务原语应始终适合单个APDU。IEC 61334-4-41:1996、10.6和附录A中规定了未经确认的写入服务。为了完整性和与使用LN referencing的服务规范的一致性,此处复制了该规范以及DLMS/COSEM的扩展。
服务原语的语义
UnconfirmedWrite服务原语应提供如表67所示的服务参数。
.request | .indication | ||
---|---|---|---|
Variable_Access_Specification { Variable_Access_Specification } Variable_Name Parameterized_Access Variable_Name Selector Parameter | M S S M M M | M(=) S (=) S (=) M (=) M (=) M (=) | |
Data { Data } | M | M (=) | |
For security parameters, see Table 50. |
UnconfirmedWrite.request服务原语的变量访问规范服务参数的不同变体的使用如表68所示。还解释了数据服务参数的使用。
如果请求的编码形式不适合单个APDU,则可以使用通用块传输机制在数据块中传输。
UnconfirmedWrite.request Variable_Access_Specification | |
---|---|
Variable_Name {Variable_Name} | 引用COSEM对象属性。Data服务参数携带要写入的数据或方法调用参数。 |
Parameterized_Access {Parameterized_Access} | 引用具有选择性访问的COSEM对象属性。Data服务参数携带要写入的数据。 |
- UnconfirmedWrite.request原语可以有一个或多个
Variable_Access_Specification
参数:
Variable_Name
变量用于引用要写入的完整COSEM对象属性或要调用的COSEM对象方法;Parameterized_Access
变量用于引用要选择性写入的COSEM对象属性。在本例中,Variable_Name
元素引用COSEM对象属性,Selector
和Parameter
元素分别携带属性规范中指定的访问选择器和访问参数。
Data服务参数携带要写入属性的值,或者要调用的方法的方法调用参数。Data参数的数量和顺序应与Variable_Access_Specification
参数的数量和顺序相同。
Write服务原语的一个可能的逻辑序列如图87 (d)所示。
UnconfirmedWrite.request原语调用SET或ACTION .request原语后,由客户端AP调用Service_Class == Unconfirmed并通过Client SN_Mapper ASE将其映射到UnconfirmedWrite.request原语。客户机AL然后构建unconfirmedWriteRequest APDU并将其发送到服务器。
UnconfirmedWrite.indication由服务器AL在接收到unconfirmedWriteRequest APDU时生成。
UnconfirmedWrite服务的协议在9.4.6.11中指定
9.3.17 The InformationReport service
功能
InformationReport服务是在事件发生时由服务器发起的非请求服务,目的是通知客户机一个或多个DLMS命名变量(映射到COSEM对象属性)的值,就像客户机请求它们一样。这是一项未确认的服务。
InformationReport服务在IEC 61334-4-41:1996, 10.7 和附录a中进行了规定。为了完整性和与使用LN referencing的服务规范保持一致,此处复制了InformationReport服务规范,以及为DLMS/COSEM所做的扩展。
服务原语的语义
InformationReport服务原语应提供如表69所示的参数。
.request | .indication | |
---|---|---|
Current_Time | M | M (=) |
Variable_Access_Specification { Variable_Access_Specification } Variable_Name |
MM | M (=)M (=) |
Data { Data } | M | M(=) |
Current_Time
参数表示InformationReport.request在哪个时间发出的。
选择Variable_Name
的Variable_Access_Specification
参数指定一个或多个DLMS命名变量-映射到COSEM对象属性-其值由服务器发送。
Data参数携带DLMS命名变量的值,其顺序与Variable_Access_Specification
参数的顺序相同。
在9.4.6.12中指定了InformationReport服务的协议。
9.3.18 Client side layer management services: the SetMapperTable.request
功能
SetMapperTable服务的功能是管理Client SN_Mapper ASE。
服务原语的语义
只有一个原语,即.request原语。它应提供如下参数,见表70。
.request | |
Protocol_Parameters | M |
Mapping_Table
是必选参数。它包含被请求服务器和AA的object_list属性的内容。内容的结构在DLMS UA 1000-1中定义。
使用
SetMapperTable.request服务由客户机AP调用,以向Client SN_Mapper ASE提供映射信息。该服务不需要在客户端和服务端之间传输任何数据。客户端AP使用此服务原语,以便在使用SN referencing时提高映射过程的效率。
9.3.19 Summary of services and LN/SN data transfer service mapping
表71和表72提供了DLMS/COSEM应用层服务的摘要。
Client side | Server side |
COSEM-OPEN.request | COSEM-OPEN.indication |
COSEM-OPEN.confirm | COSEM-OPEN.response |
COSEM-RELEASE.request | COSEM-RELEASE.indication |
COSEM-RELEASE.confirm | COSEM-RELEASE.response |
COSEM-ABORT.indication | COSEM-ABORT.indication |
Client side | Server side |
---|---|
LN referencing | |
GET.request | GET.indication |
GET.confirm | GET.response |
SET.request | SET.indication |
SET.confirm | SET.response |
ACTION.request | ACTION.indication |
ACTION.confirm | ACTION.response |
ACCESS.request | ACCESS.indication |
ACCESS.confirm | ACCESS.response |
EventNotification.indication | EventNotification.request |
TriggerEventNotificationSending.request | - |
DataNotification.indication | DataNotification.request |
SN referencing | |
Read.request | Read.indication |
Read.confirm | Read.response |
Write.request | Write.indication |
Write.confirm | Write.response |
UnconfirmedWrite.request | UnconfirmedWrite.indication |
InformationReport.indication | InformationReport.request |
DataNotification.indication | DataNotification.request |
当服务器使用SN referencing时,使用LN referencing和SN referencing的服务原语之间的映射在客户端发生。该映射在9.4.6.9、9.4.6.10、9.4.6.11和9.4.6.12中有规定。
9.4 DLMS/COSEM application layer protocol specification
9.4.1 The control function (CF)
9.4.1.1 State definitions of the client side control function
图89显示了客户端CF的状态机,另请参见图61。
- 在客户端和服务器CF的状态图上,使用了以下约定:
- 第一个字符没有"/"字符的表示状态转换触发的起点,(这么理解,左右两个 pending 就是
中间态 ,而 IDLE 和 ASSOCIATED 是 起始态 ,从起始触发的就是不带 / 的) - 以"/"字符是过程 ,也就是在转换过程中发生的
客户端CF和包括CF在内的AL的状态定义如下:
INACTIVE | 在这种状态下,CF没有任何活动:它既不向AP提供服务,也不使用支持协议层的服务。 |
IDLE | 这是没有AA存在、正在释放或正在建立时CF它是AL的状态机:不考虑低层连接,包括物理连接。另一方面,物理连接建立是在协议之外完成的的状态。然而,客户机和服务器之间的一些数据交换(如果物理通道已经建立)是可能的。CF可以处理EventNotification服务。 INACTIVE和IDLE状态之间的状态转换是由协议外部控制的。例如,可以认为CF通过在支持协议层的顶部进行实例化和绑定来实现状态从INACTIVE到IDLE的转换。通过删除给定的CF实例,可能会发生相反的转换。 |
ASSOCIATION PENDING |
当AP调用COSEM-OPEN.request原语(OPEN.req)建立AA时,CF离开IDLE状态,进入该状态(ASSOCIATION PENDING)。CF可以退出此状态,进入ASSOCIATED状态或返回IDLE状态,并生成COSEMOPEN.confirm原语,(/OPEN.cnf(OK))或(/OPEN.cnf(NOK)),取决于关联请求的结果。CF也退出此状态并返回到IDLE状态,同时生成COSEM-ABORT.indication原语(/ABORT.ind) |
ASSOCIATED | 当AA建立成功后,CF进入该状态。在此状态下,所有xDLMS服务和apdu都可用。CF一直保持这种状态,直到AP通过调用COSEM-RELEASE.request原语(RELEASE.req)释放AA。CF也退出此状态并返回到IDLE状态,同时生成COSEM-ABORT.indication原语(/ABORT.ind)。 |
ASSOCIATION RELEASE PENDING |
当AP调用COSEM-RELEASE.request原语(RELEASE.req)释放AA时,CF离开ASSOCIATED状态,进入ASSOCIATED RELEASE PENDING状态。CF保持这种状态,等待服务器对该请求的响应。由于服务器不允许拒绝释放请求,因此在退出此状态后,CF总是进入IDLE状态。CF可以通过生成COSEM-RELEASE.confirm原语来退出这个状态。在接收到来自服务器的响应后,或者在本地生成响应(/RELEASE.cnf)。CF也退出此状态并返回到IDLE状态,同时生成COSEM-ABORT.indication原语(/ABORT.ind)。 |
9.4.1.2 State definitions of the server side control function
INACTIVE | 在这种状态下,CF根本没有任何活动:它既不向AP提供服务,也不使用支持协议层的服务。 |
IDLE | 这是当没有AA存在、发布或建立它是AL的状态机:不考虑较低层连接,包括物理连接。另一方面,物理连接的建立是在协议之外完成的。时CF的状态。然而,如果物理通道已经建立,客户端和服务器之间的一些数据交换是可能的。CF可以处理EventNotification/InformationReport服务。 |
ASSOCIATION PENDING |
当客户端请求建立AA时,CF离开IDLE状态并进入该状态(ASSOCIATION PENDING),服务器AL生成COSEM-OPEN.indication原语(/OPEN.ind)。CF可以退出该状态并进入ASSOCIATED状态或返回IDLE状态,具体取决于关联请求的结果,并调用COSEM-OPEN.response原语,(/OPEN.res(OK))或(/OPEN.res(NOK))。CF也退出此状态并返回IDLE状态,同时生成COSEM-ABORT.indication指示原语(/ABORT.ind)。 |
ASSOCIATED | 当AA已经成功建立时,CF进入该状态。所有xDLMS服务和APDU在此状态下都可用。CF保持此状态,直到客户端请求释放AA,并且服务器AL生成COSEM-release.ind原语(/RERELE.ind)。CF也退出此状态,并返回IDLE状态,同时生成COSEM-ABORT.ind指示原语(/ABORT.ind)。 |
ASSOCIATION RELEASE PENDING |
当客户端请求释放AA时,CF离开ASSOCIATED状态并进入该状态(ASSOCIATION RELEASE PENDING),并且服务器AP接收到COSEM-release.indication原语(/RELEASE.ind)。CF保持在该状态,等待AP接受释放请求。由于不允许服务器拒绝释放请求,在退出该状态后,CF始终进入IDLE状态。当AP接受AA的释放并调用COSEM-RELEASE.response原语(RELEASE.res)时,CF可以退出该状态。CF也退出该状态并返回IDLE状态,生成COSEM-ABORT.indication原语(/ABORT.ind)。 |
9.4.2 The ACSE services and APDUs
DLMS/COSEM AL ACSE基于面向连接的ACSE,如ISO/IEC 15953:1999和ISO/IEC 15954:1999中规定的那样。
在关联建立过程中,功能单元用于协商ACSE用户需求。
- 定义了五个功能单元:
- Kernel功能单元;
- Authentication功能单元;
- ASO-context协商功能单元;
ISO/IEC 15953:1999和ISO/IEC 15954:1999使用术语"ASO-context"。在DLMS/COSEM中,术语"Application context"的使用与ISO/IEC 8649 / ISO/IEC 8650相同。
- 高级关联功能单元;和
- 嵌套关联功能单元。
DLMS/COSEM AL只使用Kernel
和Authentication
功能单元。
AARQ
和AARE
apdu的访问需求参数用于选择关联的功能单元。
Kernel
功能单元始终可用,包括基本服务A-ASSOCIATE、A-RELEASE。
Authentication
功能单元支持在关联建立过程中进行认证。这个功能单位的可用性是在会话建立期间协商确定的。此功能单元不包括附加服务。它向A-ASSOCIATE服务添加参数。
表73显示了DLMS/COSEM AL使用的与ACSE功能单元相关联
的服务、APDU和APDU字段。ACSE APDU的抽象语法在9.5中指定。
Functional unit |
Service | APDU | Field name | Presence |
---|---|---|---|---|
Kernel | A-ASSOCIATE | AARQ | protocol-version application-context-name called-AP-title called-AE-qualifier called-AP-invocation-identifier called-AE-invocation-identifier calling-AP-title calling-AE-qualifier calling-AP-invocation-identifier calling-AE-invocation-identifier implementation-information user-information (carrying an xDLMS Initiate.request APDU) dedicated-key response-allowed proposed-quality-of-service proposed-dlms-version-number proposed-conformance client-max-receive-pdu-size |
O M U U U U U U U U O M U U U M M M |
AARE | protocol-version application-context-name result result-source-diagnostic responding-AP-title responding-AE-qualifier responding-AP-invocation-identifier responding-AE-invocation-identifier implementation-information user-information (carrying an xDLMS initiateResponse APDU) negotiated-quality-of-service negotiated-dlms-version-number negotiated-conformance server-max-receive-pdu-size vaa-name (or carrying a confirmedServiceError APDU) |
O M M M U U U U O M S U M M M M S |
||
A-RELEASE | RLRQ | reason user-information |
U U |
|
RLRE | reason user-information |
U U |
||
Authentication | A-ASSOCIATE | AARQ | sender-acse-requirements mechanism-name calling-authentication-value |
U U U |
AARE | responder-acse-requirements mechanism-name responding-authentication-value |
U U U |
该表是根据ISO/IEC 15954:1999表2和表3编制的。字段按照它们在ACSE apdu中的顺序列出。
M 是必须的
O 是ACPM选项
U 是ACSE服务用户选项
S 从其他s参数中选择该参数作为服务器ASE环境的内部响应。
根据ISO/IEC 15953:1999,user-information为可选参数。然而,在DLMS/COSEM环境中,它在AARQ/AARE apdu中是强制性的。
- 与ISO/IEC 8649和ISO/IEC 8650-1相比,ISO/IEC 15953:1999和ISO/IEC 15954:1999有以下几点变化:
- 在ISO/IEC 15954中,协议版本在AARQ中是必选的,在AARE中是可选的。在DLMS/COSEM中,为了向后兼容,它是强制性的;
- 用ASO-context-name代替application-context-name。在DLMS/COSEM中,"application-context-name"是保留的。在ISO/IEC15 54 7.1.5.2指定:ASO-context-name是可选的。如果希望与旧的ACSE实现向后兼容,则必须提供它。因此,在DLMS/COSEM中,它是强制性的;
- 在ISO/IEC 15954中,result和result-source-diagnostic参数是可选的。ISO/IEC 15954 7.1.5.8和7.1.5.9指定:Result/Result-source-diagnostic是可选的。如果希望与旧的ACSE实现向后兼容,则必须提供它。因此,在DLMS/COSEM中,这些参数是强制性的。
- SLF NOTE
user-information
在DLMS中是必须的- AARQ和AARE中的
acse-requirements
(见9.3.2)参数用于选择功能模块启用见文中 Table 81,AARQ APDU由COSEM-OPEN.request
原语决定,AARE APDU 由COSEM-OPEN.response
原语决定
一般来说,AARQ APDU的每个字段的值是由COSEM-OPEN.request
服务原语决定的。类似地,如果AARE的每个字段的值是由COSEM-OPEN.response
原语决定的。COSEM-OPEN服务在9.3.2中指定。
- AARQ和AARE APDU的字段如下所示。在9.4.4.1中指定管理这些字段
-
protocol-version
: DLMS/COSEM AL使用默认值version 1。详情见ISO/IEC 15954:1999; -
application-context-name
: COSEM应用程序上下文名称在9.4.2.2.2中指定;ISO/IEC 15953:1999和ISO/IEC 15954:1999使用"ASO-context-name"
-
called-
,calling-
和responding- titles
,qualifiers
和invocation-identifiers
:这些可选字段携带COSEM-OPEN服务各自参数的值。详情见ISO/IEC 15954:1999; -
implementation-information
:该字段不被DLMS/COSEM AL使用,详细信息请参见ISO/IEC 15954:1999; -
user-information
:
在AARQ APDU中,它携带一个xDLMS InitiateRequest APDU,该APDU持有COSEM-OPEN.request原语的Proposed_xDLMS_Context参数的元素
在AARE APDU中,它携带一个xDLMS initiaterresponse APDU(保存Negotiated_xDLMS_Context参数的元素)或一个xDLMS confirmedServiceError APDU(保存COSEM-OPEN.response原语的xDLMS_Initiate_Error参数的元素) -
sender- and responder-acse-requirements
:该字段用于选择AARQ / AARE的可选功能单元。在COSEM中,只使用Authentication功能单元。当存在时,它携带BIT STRING {authentication(0)}的值。位集:选择认证功能单元; -
mechanism-name
: COSEM认证机制名称在9.4.2.2.3中指定; -
calling-authentication-value
和responding-authentication-value
见9.2.2.2.2; -
result
:该字段的值由如下所述的COSEM AP(acceptor)或DLMS/COSEM AL (ACPM)来确定,它用于确定COSEM-OPEN.confirm原语的Result参数的值
- 如果AARQ APDU被ACPM拒绝(COSEM-OPEN.indication原语不是由DLMS/COSEM(AL)发出的),值"拒绝(永久)"或"拒绝(暂时)"由ACPM分配;
- 否则,该值由COSEM-OPEN.response APDU的Result参数确定
-
Result-source-Diagnostic
:该字段同时包含Result source值和Diagnostic值。用于确定COSEM-OPEN.confirm原语的Failure_Type参数的值。
1.Result-source:如果AARQ被ACPM拒绝(COSEM-OPEN.indication原语不是由DLMS/COSEM(AL)发出的),ACPM分配值为"ACSE service-provider"。否则,ACPM赋值为"ACSE service-user";
1.Diagnostic:如果AARQ被ACPM拒绝,则由ACPM分配适当的值。否则,由COSEM-OPEN.response原语的Failure_Type参数决定。如果.response原语中没有包含Diagnostic参数,ACPM将赋值为"null"。 -
- RLRQ/RLRE apdu的参数,——当使用参数Use_RLRQ_RLRE==TRUE调用COSEM-RELEASE服务(见9.3.3)时使用——如下所示。
- reason:携带9.3.2中规定的适当值;
- user-information:如果存在,它携带一个xDLMS InitiateRequest/InitiateResponse APDU,保存COSEM-RELEASE.request/.response服务原语的Proposed_xDLMS_Context/Negotiated_xDLMS_Context参数的元素。见9.3.2。
9.4.2.2 Registered COSEM names
9.4.2.2.1 General
在OSI环境中,许多不同类型的网络对象必须用全局明确的名称来标识。这些网络对象包括抽象语法、传输语法、应用程序上下文、身份验证机制名称等。在大多数情况下,这些对象的名称由制定特定基本ISO标准的委员会或实施者的研讨会指定,并应进行注册。对于DLMS/COSEM,这些对象名称由DLMSUA分配,并在下面指定。
瑞士的OFCOM
的第1999.01846号决定为DLMS用户协会指定的对象标识符指定了以下前缀。
{
joint-iso-ccitt(2)
country(16)
country-name(756)
identified-organization(5)
DLMS-UA(8)
}
如ITU-T X.660 A.2.4中所述,由于历史原因,次要标识符ccitt和联合iso ccitt分别是ITU-T和联合iso ITU-T的同义词,因此可能出现在ASN.1 OBJECT IDENTIFIER值中,并且还标识相应的主整数值
- 对于DLMS/COSEM,指定了用于命名以下项目的对象标识符:
- COSEM应用程序上下文名称;
- COSEM认证机制名称;
- 加密算法ID-s。
9.4.2.2 Registered COSEM names
为了在AA内有效地交换信息,两个AE调用应相互知晓,并遵循管理交换的一组通用规则。这组常见的规则被称为AA的应用程序上下文。应用于AA的应用上下文是在其建立过程中确定的。
AA只有一个应用程序上下文。然而,组成AA的应用上下文的规则集可以包含用于在AA的生命周期更改该规则集的规则。
- 可以使用以下方法:
- 识别预先存在的应用程序上下文定义;
- 传输应用程序上下文的实际描述。
在COSEM环境中,应用程序上下文预先存在,并且在建立AA期间由其名称引用。应用程序上下文名称指定为OBJECT IDENTIFIER ASN.1类型。COSEM通过以下对象标识符值标识应用程序上下文名称:
COSEM_Application_Context_Name ::=
{
joint-iso-ccitt(2)
country(16)
country-name(756)
identified-organization(5)
DLMS-UA(8)
application-context(1)
context_id(x)
}
- 通用COSEM应用程序上下文的含义是:
- AE调用中存在两个ASE,ACSE和xDLMS ASE;
- xDLMS ASE符合IEC 61334-4-41:1996的规定;
注:对于DLMS的COSEM扩展,请参见9.1.4。
- 传输语法为A-XDR。
具体的context_id-s以及加密和未加密APDU的使用如表74所示:
Application context name | context_id | Unciphered APDUs | Ciphered APDUs |
---|---|---|---|
Logical_Name_Referencing_No_Ciphering ::= | context_id(1) | Yes | No |
Short_Name_Referencing_No_Ciphering ::= | context_id(2) | Yes | No |
Logical_Name_Referencing_With_Ciphering ::= | context_id(3) | Yes | Yes |
Short_Name_Referencing_With_Ciphering ::= | context_id(4) | Yes | Yes |
为了成功地建立AA,AARQ和AARE APDU的application-context-name参数应该携带一个"有效"名称。客户端使用COSEM-OPEN.request原语的Application_context_name参数提供的应用程序上下文的值。服务端可以返回任何值;建议的值或其支持的值。
9.4.2.2.3 The COSEM authentication mechanism name
- 客户端、服务端或两者的身份验证是DLMS/COSEM规范所涉及的安全方面之一。指定了三个身份验证安全级别
OSI分层架构中的ISO标准网络对象名,由DLMS UA分配。
- 无安全(最低级别安全)认证,见9.2.2.2.2.2;
- 低级别安全(LLS)认证,见9.2.2.2.2.3;
- 高级安全(HLS)认证,见9.2.2.2.2.4。
DLMS/COSEM通过以下通用对象标识符值来标识身份验证机制:
COSEM_Authentication_Mechanism_Name ::=
{
joint-iso-ccitt(2)
country(16)
country-name(756)
identified-organization(5)
DLMS-UA(8)
authentication_mechanism_name(2)
mechanism_id(x)
}
mechanism_id元素的值选择指定的安全机制之一:
authentication mechanism names | context_id |
COSEM_lowest_level_security_mechanism_name | mechanism_id(0) |
COSEM_low_level_security_mechanism_name | mechanism_id(1) |
COSEM_high_level_security_mechanism_name | mechanism_id(2) |
COSEM_high_level_security_mechanism_name_using_MD5 | mechanism_id(3) |
COSEM_high_level_security_mechanism_name_using_SHA-1 | mechanism_id(4) |
COSEM_high_level_security_mechanism_name_using_GMAC | mechanism_id(5) |
COSEM_high_level_security_mechanism_name_using_SHA-256 | mechanism_id(6) |
COSEM_high_level_security_mechanism_name_using_ECDSA | mechanism_id(7) |
Note 1:使用 mechanism_id(2), 是加密的 Note 2:对于新的应用,不建议使用mechanism_id(3)和mechanism_id(4)。 |
当Authentication_Mechanism_Name存在于COSEM-OPEN服务中时,应选择A-ASSOCIATE服务的认证功能单元。LLS和HLS认证的过程如9.2.2.2.2和9.2.7.3所述。
9.4.2.2.4 Cryptographic algorithm ID-s
加密算法ID标识将使用派生的加密对称密钥
的算法。见9.2.3.4.6.5。
加密算法由以下通用对象标识符值标识:
COSEM_Cryptographic_Algorithm_Id ::=
{
joint-iso-ccitt(2)
country(16)
country-name(756)
identified-organization(5)
DLMS-UA(8)
cryptographic-algorithms(3)
algorithm_id(x)
}
COSEM_cryptographic_algorithm_name_aes-gcm-128 | algorithm_id(0) |
COSEM_cryptographic_algorithm_name_aes-gcm-256 | algorithm_id(1) |
COSEM_cryptographic_algorithm_name_aes-wrap-128 | algorithm_id(2) |
COSEM_cryptographic_algorithm_name_aes-wrap-256 | algorithm_id(3) |
9.4.3 APDU encoding rules
9.4.3.1 Encoding of the ACSE APDUs
ACSE APDU应采用BER编码(ISO/IEC 8825)。这些APDU的用户信息参数应携带xDLMS InitiateRequest/InitieRespons/confirmedServiceError APDU(视情况而定),以A-XDR编码,然后以BER编码产生的OCTET STRING。
第11条和第12条给出了AARQ/AARE APDU编码的示例。
算法_id-s的值如表76所示。另见表18。
9.4.3.2 Encoding of the xDLMS APDUs
xDLMS APDU应按照IEC 61334-6:2000的规定以A-XDR编码
9.4.3.3 XML
根据"Push setup"对象的参数化,可以使用9.6中指定的XML模式将DataNotification APDU
编码为XML文档。
注:使用XML对其他APDU进行编码不在本技术报告的范围内。
9.4.4 Protocol for application association establishment
9.4.4.1 Protocol for the establishment of confirmed application associations
- 使用ACSE的A-Associate服务建立AA是DLMS/COSEM互操作性的关键要素。AA的参与者包括:
- 客户AP,提出AA;和
- 服务器AP,是否接受提议的AA。
注1:为了支持多播和广播服务,还可以在客户端AP和一组服务器AP之间建立AA。
- 图91给出了以下情况下的MSC:
- COSEM-OPEN.request原语请求一个已确认的AA;
- 建立该AA需要支持的层的连接。
希望建立已确认AA的客户端AP调用ASO的COSEM-OPEN.request原语,Service_Class==Confirmed。请注意,在调用COSEM-OPEN服务之前,必须连接PH层。xDLMS InitiateRequest APDU的响应允许参数设置为TRUE。客户端AL在生成.confirm原语之前等待AARE APDU,结果为正或负。
客户端CF进入ASSOCIATION PENDING状态。然后检查Protocol_Connection_Parameters参数。如果这表明需要建立支持的层的连接,则建立连接。然后,CF在xDLMS ASE和ACSE的帮助下,组装包含从AP接收的COSEM-OPEN.request原语参数的AARQ APDU,并将其发送到服务器。
服务器AL的CF将接收到的AARQ APDU提供给ACSE。它提取ACSE相关参数,然后将控制权交还给CF。CF随后将AARQ APDU的用户信息参数的内容(携带xDLMS InitiateRequest APDU)传递给xDLMS ASE。它检索该APDU的参数,然后将控制权交还给CF。CF使用接收到的APDU参数生成COSEM-OPEN.indication到服务器AP,并进入"ASSOCIATION PENDING"状态。
注2:COSEM-OPEN.indication原语的一些服务参数(地址信息,User_information)不是来自AARQ APDU,而是来自承载AARQ AP DU的支持层帧。在一些通信配置文件中,COSEM-OPEN服务的Service_Class参数链接到支持层的帧类型。在其他一些通信配置文件中,它链接到xDLMS Initiate.request APDU的允许响应字段。另请参见10。
注3:ASE仅提取参数;它们的解释以及是否可以接受所提出的AA是服务器AP的工作。
Kernel
功能单元的字段:
application-context-name
:它携带客户端为关联提议的COSEM_Application_Context_Name
;calling-AP-title
:当提议的应用程序上下文使用加密时,它应该携带客户端系统标题。如果在注册过程中已经发送了客户端系统标题,如在S-FSK PLC配置文件中,则calling-AP-title
字段应携带相同的系统标题。否则,应拒绝该AA并发送适当的诊断信息;calling_AE_invocation_identifier
:该字段支持客户端用户识别过程;见DLMS UA 1000-1 Ed. 12.2: 2017,4.4.2;calling-AE-qualifier
:该字段可用于传输客户端数字签名密钥的公钥证书。
authentication
功能单元字段(当呈现的时候):- sender-acse-requirements
- 如果不存在或存在但bit0 = 0,则不选择
authentication
功能单元。authentication
功能单元的以下字段可以忽略; - 如果存在且bit0 = 1,则选择认证功能单元;
- 如果不存在或存在但bit0 = 0,则不选择
mechanism-name
:它携带客户端为关联提议的COSEM_Authentication_Mechanism_Name
;calling-authentication-value
:携带客户端生成的认证值。
如果mechanism-name
或calling-authentication-value
字段的值不可接受,则拒绝提议的AA。
- sender-acse-requirements
- 当Kernel和authentication功能单元的字段解析完成后,服务器继续解析由AARQ的
user-information
字段携带的xDLMS InitiateRequest APDU的参数:
dedicated-key
:它携带在建立的AA中使用的专用密钥;response-allowed
:如果提议的AA被确认,且该参数值为TRUE(默认值),服务器将返回一个AARE APDU。否则,服务器将不响应。另见第10条;proposed-dlms-version-number
,见9.1.4.6;proposed-conformance
,见9.4.6.1;client-max-receive-pdu-size
,参见9.1.4.8
如果所提出的AA的所有元素都是可接受的,则服务器AP调用具有以下参数的COSEM-OPEN.response服务原语:
Application_Context_Name
:与提议的名称相同;Result
,可接受Failure_Type
:Result-source:acse-service-user;Diagnostic:nullResponding_AP_Title
:如果协商的应用程序上下文使用加密,则应携带服务器系统标题。- 如果在注册过程中已经发送了服务器系统标题,如S-FSK PLC配置文件,则Responding_AP_title参数应携带相同的系统标题。
- 否则,AA应由客户端中止;
Responding_AE_Qualifier
:该字段可用于传输服务器数字签名密钥的公钥证书;- AARE authentication单元的字段:
- (Responder_)ACSE_Requirements:
- 当未使用安全性(最低级别安全性)authentication或低级别安全性(LLS)authentication时,此字段不应存在,或者如果存在,则bit 0(authentication)应设置为0。可以忽略authentication功能单元的以下任何字段;
- 当使用高级安全(HLS)认证时,该字段应存在,并且bit 0(authentication)应设置为1;
- Security_Mechanism_Name:应携带COSEM_Authentication_Mechanism_Name协商
- Responding_Authentication_Value:携带服务器生成的认证值(StoC)。
- (Responder_)ACSE_Requirements:
- Negotiated_xDLMS_Context
CF在xDLMS ASE和ACSE的帮助下组装AARE APDU,并通过支持的层协议将其发送到客户端AL,然后进入ASSOCIATED状态。提议的AA现已成立;服务器能够接收xDLMS数据传输服务请求(包括已确认和未确认),并在此AA内发送对已确认服务请求的响应。
在客户端,在ACSE和xDLMS ASE的帮助下提取接收到的AARE APDU的字段,并通过COSEM-OPEN.conf服务原语传递给客户端AP。同时,客户端AL进入"ASSOCIATED"状态。现在通过协商应用程序上下文和xDLMS上下文来建立AA。
如果客户端提出的应用程序上下文不可接受,或者客户端的authentication不成功,则使用以下参数调用COSEM-OPEN.response原语:
Application_Context_Name
:与提议的或服务器支持的名称相同;Result
:永久拒绝或被瞬间拒绝;Failure_Type
:Result-source: acse-service-user; Diagnostic: 适当的值User_Information
:xDLMS InitiateResponse APDU,具有服务器支持的xDLMS上下文的参数。
如果客户端提出的应用程序上下文是可接受的,并且客户端的authentication成功,但xDLMS上下文不能被接受,则应使用以下参数调用COSEM-OPEN.response原语:
Application_Context_Name
:与提议的名称相同;Result
:永久拒绝或被瞬间拒绝;Failure_Type
:Result-source: acse-service-user; Diagnostic:未给出原因;xDLMS_Initiate_Error
,表示不接受提议的xDLMS上下文的原因。
在这两种情况下,在调用.response原语时,CF组装AARE APDU,并通过支持的层协议将其发送到客户端。建议的AA没有建立,服务器CF返回到IDLE状态。
在客户端,在ACSE和xDLMS ASE的帮助下提取接收到的AARE APDU的字段,并通过COSEM-OPEN.conf原语传递给客户端AP。建议的AA没有建立,客户端CF返回到IDLE状态。
服务器ACSE可能无法支持所请求的关联,例如,如果AARQ语法或ACSE协议版本不可接受。在这种情况下,它会向客户端返回一个带有适当Result参数的COSEMOPEN.response原语。AARE APDU的结果源诊断字段被适当地分配了符号值"acse-serviceprovider"。未发出COSEM-OPEN.indication原语。该关联尚未建立。
9.4.4.2 Repeated COSEM-OPEN service invocations
如果客户端AP引用已建立的AA调用COSEM-OPEN.request原语,则AL本地否定地确认该请求,理由是所请求的AA已经存在。请注意,对于预先建立的AA,情况总是如此。见9.4.4.4。
然而,如果服务器AL接收到引用已经存在的AA的AARQ APDU,则它简单地丢弃该AARQ,或者,如果它被实现,则它也可以使用可选的exception-responseAPDU进行响应
9.4.4.3 Establishment of unconfirmed application associations
希望建立未确认AA的客户端AP调用ASO的COSEM-OPEN.request原语,Service_Class==unconfirmed。由AARQ的用户信息参数携带的xDLMS-InitiateRequest APDU的响应允许参数设置为FALSE。客户端AL不等待来自服务器的任何响应:.confirm原语是本地生成的。否则,程序与建立已确认的AAs的情况相同。
由于未确认AA的建立不需要服务器AP响应来自客户端的关联请求,在某些情况下,例如在单向通信或广播的情况下,建立未确认AA是唯一的可行的。
在建立了未确认的AA之后,使用LN referencing的xDLMS数据传输服务只能以未确认的方式调用,直到关联被释放。SN referencing时,只能使用UnconfirmedWrite服务。
9.4.4.4 Pre-established application associations
预先建立的AAs的目的是简化数据交换。取消了使用COSEM-OPEN和COSEM-release服务的AA建立和发布阶段(图4中的第1和第3阶段),只使用数据传输服务。本技术报告没有具体说明如何建立此类AAs:可以认为,已经这样做了。从较低层能够在客户端和服务器之间传输APDU的那一刻起,可以认为预先建立的AA存在。
对于所有AA,逻辑设备也应包含用于预先建立的关联的关联LN/SN接口对象。
预先建立的AA可以是确认的,也可以是未确认的(取决于预先建立的方式)。
预先建立的AA无法释放。
9.4.5 Protocol for application association release
9.4.5.1 Overview
现有的AA可以优雅的释放,也可以不优雅的释放。优雅的释放由客户端AP发起。当AP发生意外事件(例如检测到物理断开连接)时,会发生非正常释放。
9.4.5.2 Graceful release of an application association
DLMS/COSEM提供了两种释放AA的机制:
- 通过断开AL的
支持的层
- 通过使用ACSE A-Release服务。
第一种机制应在AL的支持的层
面向连接的所有配置文件中得到支持。3层,基于HDLC,面向连接的配置文件
。
要以这种方式释放AA,应在Use_RLRQ_RLRE
参数不存在或FALSE的情况下调用COSEM-RELEASE服务。断开支持的层应释放在支持的层连接上构建的所有AAs。
第二种机制可用于在不断开支持的层应的情况下释放AA。当支持的层应为无连接时,应在所有配置文件中得到支持。当支持层是面向连接的,但连接不是由AL管理的,或者由于其他应用程序可能使用支持的层而无法断开支持的层时,或者当需要保护COSEM-RELESE服务时,也可以使用它。这是释放未经证实的AAs的唯一途径。
要以这种方式释放AA,应使用Use_RLRQ_RLRE参数=TRUE来调用COSEM-RELEASE服务。如9.3.3中所述,可以通过在RLRQ/RLRE APDU的用户信息字段中分别包含加密的xDLMS InitiateRequest/IninitiateResponse来保护COSEM-RELESE服务,从而防止潜在的拒绝服务攻击。
使用ACSE A-RELEASE服务释放AA的示例如图92所示
AA的释放可能需要CF的ASE之间的内部通信。这些未在图92至图94中显示

希望使用A-release服务释放AA的客户端AP应调用Use_RLRQ_RLRETRUE的COSEMRELEASE.request服务原语。客户端CF进入ASSOCIATION RELEASE PENDING状态。然后,它构造一个RLRQ APDU并将其发送到服务器。如果要释放的AA已经用加密上下文建立,则RLRQ APDU的用户信息字段可以包含加密的xDLMS InitiateRequest APDU。参见9.3.3。
当服务器AL CF接收到RLRQ APDU时,它首先检查用户信息字段是否包含加密的xDLMS InitiateRequest APDU。如果是,它将尝试对其进行解密。如果成功,它将进入ASSOCIATION RELEASE PENDING状态,并生成一个具有Use_RLRQ_RLRETRUE的COSEM-REASE.indication原语。否则,它将静默地丢弃RLRQ APDU并保持在ASSOCIATED状态。
.response原语由服务器AP调用,以指示AA的释放是否被接受,但仅指示要释放的AA是否被确认。请注意,服务器AP不能拒绝释放请求。在接收到.response原语时,服务器AL CF构造RLRE APDU并将其发送到客户端。如果RLRQ APDU包含加密的xDLMS初始请求APDU,则RLRE ADU应包含加密的xDLMS初始响应APDU。服务器AL CF返回IDLE状态。
确认原语由客户端AL CF在接收到RLRE APDU时生成。支持的层未断开。客户端AL CF返回IDLE状态。
如果接收到的RLRE APDU包含加密的xDLMS Initiate Response APDU,但无法解密,则应丢弃该RLRE APDU。由客户来处理这种情况。
图93给出了通过断开相应的下层连接来优雅地释放已确认AA的示例。

客户端AP如果不希望使用A-release服务来释放AA,则调用Use_RLRQ_RLRE==FALSE(就是不使用ACSE 的 A-RELEASE 服务,见 9.3.3)或不存在Use_RLRQ_RLRE
的COSEM-RELEASE.request原语。客户端AL CF进入ASSOCATION RELEASE PENDING状态。
在RLRQ服务是强制性的通信配置文件中,在没有Use_RLRQ_RLRE或Use_RLRQ _RLRE==FALSE的情况下调用.request原语可能会导致错误:.request应在本地进行否认。客户端AL CF返回IDLE状态。
当客户端AL CF接收到.request原语时,它会向服务器发送XX-DISCNNECT.request原语。
当服务器AL CF接收到XX-DISCNNECT.request原语时,CF进入ASSOCATION RELEASE PENDING状态。COSEM-RELEASE.indication原语由服务器AL CF在Use_RLRQ_RLRE==FALSE(就是不使用ACSE的A-RELEASE服务,见 9.3.3)或不存在Use_RLRQ_RLRE
的情况下生成。
COSEM-REASE.response原语由服务器AP调用,以指示AA的释放是否被接受。请注意,服务器AP不能拒绝释放请求。在接收到该原语后,服务器AL CF向客户端发送XX-DISCNNECT.response原语,并返回IDLE状态。
当接收到XX-DISCONNECT.confirm原语时,客户端AL会生成COSEM-RELEASE.confirm原语。支持的层断开。客户端AL CF返回IDLE状态。
- SLF NOTE
- Use_RLRQ_RLRE 参数为 TRUE (就是使用 ACSE 的 A-RELEASE服务),COSEM-RELEASE 服务可以包含加密的 xDLMS InitiateRequest /InitiateResponse 在 RLRQ / RLRE APDUs 的 user- information参数中,从而防止潜在的 拒绝服务攻击 (没有保护的话谁都可以断开连接)。
9.4.5.3 Non-graceful release of an application association
各种事件可能导致AA的不优雅释放:检测到任何较低层连接(包括物理连接)的断开、检测到本地错误等。
在COSEM-ABORT服务的帮助下,向COSEM AP指示AA的非优雅释放。此服务的Diagnostics参数表示不安全释放AA的原因。AA的非优雅释放不是选择性的:如果发生这种情况,所有现有的关联(除了预先建立的关联)都将被终止。
图94显示了由于检测到物理断开而中止AA的消息序列图。
9.4.6 Protocol for the data transfer services
9.4.6.1 Negotiation of services and options -- the conformance block
一致性块允许客户端和服务器使用相同的DLMS/COSEM协议,但支持不同的功能来协商一组兼容的功能,以便它们可以通信。它由COSEM-OPEN服务的DLMS_Conformance携带。
在DLMS/COSEM中,没有一个服务或选项是强制性的。要使用的服务或选项是通过COSEM-OPEN服务协商的(xDLMS InitiateRequest APDU的提议一致性参数和xDLMS initiaterresponse APDU的协商一致性参数)。实现的服务应完全符合其规范。如果在协商的一致性块中不存在服务或选项,则客户端不应该请求它。
xDLMS一致性块可以通过其标签:APPLICATION 31与IEC 61334-4-41:1996中指定的DLMS一致性块区分开来。如表77所示。
Conformance block bit | Reserved | LN referencing | SN referencing |
---|---|---|---|
0 | x | ||
1 | general-protection1 | general-protection1 | |
2 | general-block-transfer | general-block-transfer | |
3 | read | ||
4 | write | ||
5 | unconfirmed-write | ||
6 | x | ||
7 | x | ||
8 | attribute0-supported-with-set | ||
9 | priority-mgmt-supported | ||
10 | attribute0-supported-with-get | ||
11 | block-transfer-with-get-or-read | block-transfer-with-get-or-read | |
12 | block-transfer-with-set-or-write | block-transfer-with-set-or-write | |
13 | block-transfer-with-action | ||
14 | multiple-references | multiple-references | |
15 | information-report | ||
16 | data-notification | data-notification | |
17 | access | ||
18 | parameterized-access | ||
19 | get | ||
20 | set | ||
21 | selective-access | ||
22 | event-notification | ||
23 | action | ||
1general-protection includes general-glo-ciphering, general-ded-ciphering, general-ciphering and general- signing |
- SLF NOTE
- 一致性块,用于协商双方支持的功能,COSEM-OPEN 服务中:xDLMS InitiateRequest APDU 中的
proposed-conformance
参数和 xDLMS InitiateResponse APDU 中的negotiated-conformance
- 图中提到了只有 get、set、action 可以配置为使用block-transfer,应该就是 service-specific block transfer,和 9.4.6.6 ACCESS 服务不支持 service-specific block transfer 相符
9.4.6.2 Confirmed and unconfirmed xDLMS service invocations
通常,可以以已确认或未确认的方式调用xDLMS服务。服务原语的时间序列对应于:
- 图87 已确认的服务调用的a)项;和
- 图87 在未确认的服务调用d)项。
客户机AP希望访问COSEM对象的属性或方法的调用适当的.request服务原语。客户机AL构造与.request原语相对应的APDU,并将其发送给服务器。
服务器AP在收到.indication原语后,检查是否可以提供服务(有效性、客户端访问权限、可用性等)。如果一切正常,则在本地将所需的服务应用于相应的"real"对象。在确认服务的情况下,服务器AP调用适当的.response原语。服务器AL构造与.response原语相对应的APDU,并将其发送到服务器。客户机AL生成.confirm原语。
如果服务器AL不能处理已确认的服务请求——例如,请求没有首先建立一个AA就收到了,或者请求在其他方面是错误的——它要么被丢弃,要么在可能的情况下,服务器AL响应一个confirmedServiceError APDU,或者在实现时,响应一个ExceptionResponse APDU。这些apdu可能包含关于无法处理请求的原因的诊断信息。它们在9.5中定义。
在已确认的AAs中,可以以已确认或未确认的方式调用xDLMS服务。
在未经确认的AAs中,只能以未经确认的方式调用xDLMS服务。这样,就可以避免在多播和/或广播的情况下由于潜在的多重响应而产生的冲突。
对于未经确认的服务,有三种不同类型的目标地址:individual
, group
或者broadcast
.。根据目的地址类型,接收站对传入APDUS的处理方式不同,具体如下:
- 带有COSEM逻辑设备
individual
地址的XX-APDUs。如果在已建立的AA内收到,则应将其发送到COSEM逻辑设备地址,否则将被丢弃; - 带有一组COSEM逻辑设备的
group
地址的XX-APDUs。这些将被发送到COSEM逻辑设备组的地址。但是,如果客户端与所寻址的COSEM逻辑设备组之间没有建立AA,则将丢弃收到的消息; - 带有
broadcast
地址的XX-APDUs应发送到所有COSEM逻辑设备。但是,如果客户端与全站地址之间没有建立AA,则丢弃收到的消息。
说明客户端与一组逻辑设备之间的非确认AAs是通过设置为Service_Class == Unconfirmed的COSEM-OPEN服务和一组逻辑设备地址(如
broadcast
地址)建立的。
9.4.6.3 Protocol for the GET service
当客户端AP希望读取一个或多个COSEM对象属性的值时,它使用GET服务。
如9.3.6中所述,请求的编码形式应始终适合于单个APDU。
另一方面,结果可能太长而无法装入单个APDU。在这种情况下,既可以service-specific block transfer机制或general block transfer机制。它通过conformance block的bit 2或bit 11进行协商,参见9.4.6.1。
在一些DLMS/COSEM通信配置文件中,可以使用分段来传输长apdu。
GET服务原语类型和相应的APDUs如表78所示。
GET .req / .ind | Request APDU | Response APDU | GET .res / .cnf |
---|---|---|---|
NORMAL | Get-Request-Normal | Get-Response-Normal | NORMAL |
Get-Response-With-Datablock with Last-Block = FALSE | ONE-BLOCK | ||
NEXT | Get-Request-Next | Get-Response-With-Datablock with Last-Block = FALSE | ONE-BLOCK |
Get-Response-With-Datablock with Last-Block = TRUE | LAST-BLOCK | ||
WITH-LIST | Get-Request-With-List | Get-Response-With-List | WITH-LIST |
Get-Response-With-Datablock with Last-Block = FALSE | ONE-BLOCK |
图95显示了成功情况下确认的GET服务的MSC,没有块传输
图96显示了成功情况下已确认GET服务的MSC,使用service-specific block transfer以三个块的形式返回结果。

GET.request原语视情况而定调用Request_Type == NORMAL或WITH-LIST。由于在这种情况下,要返回的数据太长,无法放入单个APDU中,因此服务器AP以块的形式发送数据。首先,对数据进行编码,就好像它适合单个APDU一样:
- 如果请求
单个属性
的值,则仅对类型和值进行编码(Data)。如果Data无法交付,则响应类型为GET-NORMAL,带有Data_Access_Result; - 如果请求
属性列表
的值,那么结果列表应该被编码:对于每个属性,要么Data要么Data_Access_Result
。结果是一系列字节,B1, B2, B3,....BN。服务器在收到第一个GET.indication原语后可以生成一个完整响应。
服务器AP组装一个DataBlock_G
结构体:
- Last_Block == FALSE;
- Block_Number == 1;
建议从1开始编号
- Result(Raw_Data)==编码数据的前K字节:B1, B2, B3,....BK
服务器AP随后调用带有Response_Type == ONE-BLOCK的GET-RESPONSE-ONE-BLOCK服务原语,并携带此DataBlock-G结构。
在接收到.response原语之后,服务器AL构建一个携带.response原语参数的Get-Response-With-Datablock APDU,并将其发送给客户端。
在接收到这个APDU后,客户端AL使用Response_Type == ONE-BLOCK生成一个.confirm原语。客户机AP现在被告知响应是在几个块中提供的。存储接收到的数据块(B1, B2, B3,....BK),然后确认其接收,并通过调用GET-REQUEST-NEXT服务原语请求下一个。块号应与接收到的数据块的块号相同。客户机AL构建Get-Request-Next APDU并将其发送到服务器。
当服务器AL调用GET时。使用Request_Type == NEXT指示原语,服务器AP准备并发送下一个数据块,包括BK+1, BK+2, BK+3,....BL, block-number == 2。这种发送数据块和确认的交换一直持续到最后一个数据块,其中包含BM+1, BM+2, BM+3,....,则发送BN。最后一个GET.response原语在DataBlock-G结构Last_BLOCK==TRUE中或者Response_Type == LAST-BLOCK调用。客户端未确认最后一个数据块。
在整个过程中,每个原语中的Invoke_Id和Priority参数应该是相同的。
如果在长数据传输期间,服务器接收到另一个服务请求,则根据优先级规则和优先级管理设置(Conformance block的bit 9)为其提供服务。
如果在长数据传输过程中出现任何错误,传输将被终止。错误情况有:
- a)服务器由于任何原因不能提供下一个数据块。在这种情况下,服务器AP将调用GET-RESPONSE-LAST-BLOCK服务原语。Result参数应该包含一个DataBlock_G结构体,该结构体具有:
- Last_Block == TRUE;
- Block_Number ==客户端确认的区块数+1;
- Result == Data_Access_Result,表示失败原因。
- b)GET-REQUEST-NEXT服务原语中的Block_Number参数不等于服务器发送的前一个块的数量。服务器将此解释为客户端想要中止正在进行的传输。在这种情况下,服务器AP将调用GET-RESPONSELAST-BLOCK服务原语。Result参数应该包含一个DataBlock_G结构体,该结构体具有:
- Last_Block == TRUE;
- Block_Number ==等于从客户端接收到的区块号;
- Result == Data-Access-Result, long-get-aborted。
- c)当没有长数据传输正在进行时,服务器可能会收到Get-Request-Next APDU。在这种情况下,服务器AP将调用GET-RESPONSE-LAST-BLOCK服务原语。Result参数应该包含一个DataBlock_G结构体,该结构体具有:
- Last-block == TRUE;
- block - number ==等于从客户端接收到的区块号;
- Result == Data-Access-Result, no-long-get-in-progress。
- d)服务器发送的区块号不等于序列中的下一个。在这种情况下,客户端应中止区块转移(参见情况b)。
如果在上述错误情况下,服务器由于任何原因无法调用GET-RESPONSE-LAST-BLOCK服务原语,则应调用GET-RESPONSE-NORMAL服务原语,并使用Data-Access-Result参数指示失败原因。服务器发送一个GetResponse-Normal APDU。
错误情况b)的MSC, long get aborted,如图97所示:

- SLF NOTE
- 有多个属性的情况下,每个属性都要回对应的 Data 或 Data_Access_Result
- 通过 conformance block 协商在APDU过长时是否使用GBT或service-specific block transfer
- 结合 9.3.6 对GET的说明,AP负责Data的编解码同时可以对Data进行分块,也就是 service-specific block transfer的基础。其中分块可以是按字节不按逻辑分,也可以按逻辑分(每块都能自解析)。这样的话服务端就可以分段生成回复,对于已经发送的块可以释放内存,减少内存占用
- 发送接收流程:
第一个.response 的 DataBlock_G(见 9.3.7):- Last_Block == FALSE;
- Block_Number == 1;
- Result (Raw_Data) == the first K bytes of the encoded data: B1, B2, B3,....BK
客户端 AP 继续发送 GET-REQUEST-NEXT, Block_Number 和 上一次接受到的回复 相同 ,也就是 1(可以理解为客户端确认序号,表示 1 已确认)。服务端 AP收到请求后继续发 Block_Number 为2 的块
9.4.6.4 Protocol for the SET service
当客户端AP希望写入一个或多个COSEM对象属性的值时,它使用set服务。
如9.3.7所述,请求的编码形式可能适合于单个请求,也可能不适合于单个请求。在后一种情况下,可以使用service-specific block transfer机制或general block transfer机制。它通过conformance block的bit 2或第bit 12进行协商,参见9.4.6.1。
注1:在某些DLMS/COSEM通信配置文件中,分段可用于传输长apdu。
SET服务原语类型和相应的apdu如表79所示。
SET .req / .ind | Request APDU | Response APDU | SET .res / .cnf |
---|---|---|---|
NORMAL | Set-Request-Normal | Set-Response-Normal | NORMAL |
FIRST-BLOCK | Set-Request-With-First- DatablockLast-Block = FALSE | Set-Response-Datablock | ACK-BLOCK |
ONE-BLOCK | Set-Request-With-Datablock Last-Block = FALSE | ||
LAST-BLOCK | Set-Request-With-Datablock Last-Block = TRUE | Set-Response-Last-Datablock | LAST-BLOCK |
LAST-BLOCK- WITH-LIST | |||
WITH-LIST | Set-Request-With-List | Set-Response-With-List | WITH-LIST |
FIRST-BLOCK- WITH-LIST | Set-Request-With-List-And-With- First-Datablock | Set-Response-Datablock | ACK-BLOCK |
图98显示了已确认的SET服务的MSC,在成功的情况下,没有块传输。

图99显示了成功情况下已确认的SET服务的MSC,使用service-specific block transfer机制,以三个块的形式发送请求。
在这种情况下,要发送的数据太长,无法容纳在单个APDU中,因此客户端AP以块的形式发送数据。首先,对数据进行编码,就好像它适合单个APDU一样。结果是一系列字节,B1, B2,B3,....BN。客户端可以一步生成完整的请求(B1, B2,B3、....BN),也可以动态地生成。
- 客户端AP组装一个DataBlock_SA结构:
- Last_Block == FALSE;
- Block_Number == 1;
- Raw_Data ==编码数据的前K字节:B1, B2,B3,....BK。
客户端AP随后调用SET-REQUEST-FIRST-BLOCK或SET-REQUEST-FIRST-BLOCKWITH-LIST服务原语,并携带属性引用和这个DataBlockSA结构。
在接收到.request原语之后,客户机AL构建适当的Set-Request APDU,其中包含.request原语的参数,并将其发送给服务器。
服务器存储接收到的数据块,然后确认其接收,并通过调用具有response_TypeACK-block且块号与接收到的块号相同的SET.response原语来请求下一个数据块。
为了发送携带BK+1, BK+2, BK+3...BL的下一个数据块,客户端AP调用SET-REQUESTONE-block服务原语。这种发送数据块和确认的交换继续进行,直到通过调用Last_blockTRUE的SETREQUEST-last-block服务原语发送携带BM、BM+1、BM+2…BN的最后一个数据块。
当这些原语被调用时,客户机AL构建一个带有DataBlock_SA结构的Set-Request-With-Datablock APDU,并将这些APDU发送给服务器。
当服务器AP接收到最后一个数据帧时,它会根据需要调用SET-RESPONSE-LAST-BLOCK或SETRESPONSE-LAST-BLOCK-WITH-LIST服务原语。Result参数携带完整SET服务调用的结果。Block_Number参数确认接收到最后一个区块。
在整个过程中,每个原语中的Invoke_Id和Priority参数应该是相同的。
如果在长数据传输期间,服务器接收到另一个服务请求,则根据优先级规则和优先级管理设置(Conformance block bit 9)为其提供服务。
- 如果在长数据传输过程中出现任何错误,传输将被终止。错误情况有:
- a)由于任何原因,服务器无法处理接收到的数据块。在这种情况下,服务器AP应酌情调用SET-RESPONSE-LAST-BLOCK或SET-RESPONSE-LAST-BLOCK-WITH-LIST服务原语。Result参数表示终止传输的原因;
- b) SET-REQUEST-ONE-BLOCK服务原语中的Block_Number参数不等于服务器期望的块数(上次接收到的+ 1)。服务器将此解释为客户端想要中止正在进行的传输。在这种情况下,服务器AP应调用SETRESPONSE-LAST-BLOCK或SET-RESPONSE-LAST-BLOCK-WITH-LIST服务原语,并适当使用结果参数Data_Access_Result == long-set-aborted;
- c)当没有长数据传输正在进行时,服务器可能会收到Set-Request-With-Datablock APDU。在这种情况下,服务器AP应调用带有结果参数Data_Access_Result == no-long-set-in-progress的SET-RESPONSE-LAST-BLOCK服务原语。
如果在上述错误情况下,由于任何原因服务器无法调用SET-RESPONSE-LAST-BLOCK服务原语,那么它将调用SET-RESPONSE-NORMAL服务原语,并使用DataAccess-Result参数指示失败原因。
9.4.6.5 Protocol for the ACTION service
当客户机AP希望调用一个或多个COSEM对象方法时,它使用ACTION服务。如9.3.8所述,ACTION服务包括两个阶段。
如果方法引用和方法调用参数或返回参数不适合单个APDU,则可以使用service-specific block transfer机制或general block transfer机制。它通过conformance block的bit 2或bit 13进行协商,参见9.4.6.1。
在一些DLMS/COSEM通信配置文件中,可以使用分段来传输长apdu。
ACTION服务原语类型和相应的apdu如表80所示
SET .req / .ind | Request APDU | Response APDU | SET .res / .cnf |
---|---|---|---|
NORMAL | Action-Request-Normal | Action-Response-Normal | NORMAL |
Action-Response-With-Pblock | ONE-BLOCK | ||
NEXT | Action-Request-Next-Pblock | Action-Response-With-Pblock | ONE-BLOCK |
Action-Response-With-Pblock | LAST-BLOCK | ||
FIRST-BLOCK | Action-Request-With-First- Pblock | Action-Response-Next-Pblock | NEXT |
ONE-BLOCK | Action-Request-With-Pblock | ||
LAST-BLOCK | Action-Request-With-Pblock | Action-Response-Normal | NORMAL |
Action-Response-With-Pblock | ONE-BLOCK | ||
WITH-LIST | Action-Request-With-List | Action-Response-With-List | WITH-LIST |
Action-Response-With-Pblock | ONE-BLOCK | ||
WITH-LIST-AND- FIRST-BLOCK | Action-Request-With-List-And- With-First-Pblock | Action-Response-Next-Pblock | NEXT |
图100显示了成功情况下确认的ACTION服务的MSC,没有块传输。

- ACTION服务可以在两个阶段上传输数据:
- 在第一阶段,客户端发送ACTION。使用所引用的方法的方法调用参数请求,并且服务器确认它们。与SET服务的情况一样,这个过程本质上是相同的;
- 在第二阶段,服务器发送ACTION。使用调用方法的结果和返回参数响应。该过程本质上与GET服务的情况相同。
在整个过程中,每个原语中的Invoke_Id和Priority参数应该是相同的。
如果在长数据传输期间,服务器接收到另一个服务请求,则根据优先级规则和优先级管理设置(Conformance block bit 9)为其提供服务。
图101演示了使用特定于服务的块传输机制在两个方向上进行块传输的情况下的MSC。
如果长数据传输过程中出现任何错误,传输将被终止。错误情况与GET和SET服务的情况相同。
9.4.6.6 Protocol for the ACCESS service
客户端可以使用ACCESS服务读取或写入一个或多个COSEM对象属性的值,或者调用一个或多个方法。
ACCESS服务的协议是通过消息序列图来指定的,包括它与general block transfer和general message protection一起使用的情况。
请参见9.1.4.4.7、9.3.5和9.4.6.13。
图102显示了用于获取一个COSEM对象属性值的ACCESS服务的MSC。该请求适合单个APDU。响应很长,因此服务器使用GBT机制发送回响应:访问-响应APDU的一部分由通用general block transfer APDU的块数据字段携带。
当客户端接收到第一个general block transfer APDU时,它切换到GBT,宣布支持window size=3的流。
图103显示了用于携带请求列表的ACCESS服务的MSC,它不适合单个APDU,因此使用GBT。响应也很长,因此服务器也使用GBT。双方都知道一个优先级,另一方支持window size = 3的流。

- SLF NOTE
- ACCESS 是不支持 service-specific block transfer 吗,文中只给了GBT 的例子,没有更新:见 9.4.6.1,conformance block不包含,不支持
- 图中的 FIRST 和 LAST 应该是 partial service invocations 部分服务调用(FIRST-PART,LAST-PART), 不是 service-specific block transfer
- ❓️在这个例子中为什么客户端 AL 可以在不知道对方接收窗口的情况下发送 W=3 的GBT,如果按照 AL 层的 GBT 参数必须由 AP 提供来看应该是错误的
- 有个要注意的是对于 GET,SET,ACTION,ACCESS , 客户端 总是作为 主动方,也就是管理重发的角色。服务端发出去的都不需要客户端回确认,超时也不重发
9.4.6.7 Protocol of the DataNotification service
当服务器AP调用DataNotification.request服务原语,服务器AL构建DataNotification APDU并将其发送到客户端。
当客户端AL接收到这个APDU时,它调用DataNotification.indication服务原语。
如果服务原语很长,则可以使用partial service invocations。
如果服务原语的编码形式太长,则可以使用general block transfer机制。可以使用service-specific的块传输机制或general block transfer机制。
参见图118
9.4.6.8 Protocol for the EventNotification service
在调用EventNotification.request服务时,服务器AL构建一个event-notificationrequest请求APDU。发送此APDU的可能性取决于通信配置文件和较低层的连接状态。因此,在第10节将进一步讨论EventNotification服务的协议。
- 在任何情况下,为了在没有客户端请求的情况下将属性的值发送给客户端:
- 服务器使用EventNotification.request服务原语;
- 在调用此原语时,服务器AL构建一个event-notification-request APDU;
- 该APDU由支持的层服务在第一次提供给客户端时携带。服务类型和第一次的可用性取决于所使用的通信配置文件;
- 在接收到事件通知请求APDU后,客户端AL生成一个事件通知。COSEM客户端AP的指示原语;
在客户端,它始终是EventNotification.indication,独立于服务器使用的引用方案(LN或SN)。
- 默认情况下,事件通知从管理逻辑设备(服务器)发送到管理AP(客户端)。
9.4.6.9 Protocol for the Read service
- 如9.3.14所述,当服务器使用SN referencing时,使用Read服务,读取COSEM对象属性,或者在期望返回参数时调用Method:
- 在第一种情况下,GET.request服务原语映射到Read.request原语和Read.confirm原语映射到GET.confirm原语。对应的SN apdu及其对应关系如表81所示;
- 在第二种情况下,ACTION.request服务原语映射到Read.request原语和Read.confirm原语被映射到ACTION.response原语。其对应关系及对应的SN apdu如表82所示。
- 在下面的映射表中,使用如下表示法:
+ 对于LN服务,只显示请求和响应类型,而不显示服务参数;
+ 对于SN服务,服务原语的名称后跟括号中的服务参数。服务参数名称元素大写,并用下划线连接,以表示单个实体。可以重复的参数用花括号表示。Variable_Access_Specification参数可以采取的选择列在符号"="后面。选项由竖线"|"分隔。
+ 对于SN APDU, APDU的名称后跟符号"::="和括号中的字段。字段名元素不大写,并用破折号连接以表示单个实体。可能重复的字段显示在花括号中。选项由竖线"|"分隔。
From GET.request of type | To Read.request | SN APDU |
---|---|---|
NORMAL | Read.request (Variable_Access_Specification) Variable_Access_Specification = Variable_Name|Parameterized_Access; | ReadRequest ::= (variable-name | parameterized-access) |
NEXT | Read.request (Variable_Access_Specification) Variable_Access_Specification = Block_Number_Access; | ReadRequest ::= (block-number-access) |
WITH-LIST | Read.request ({Variable_Access_Specification}) Variable_Access_Specification = Variable_Name|Parameterized_Access; | ReadRequest ::= ({variable-name I parameterized-access}) |
To GET.confirm of type | SN APDU | From Read.response |
NORMAL | ReadResponse ::= (data | data-access-error) | Read.response (Data | Data_Access_Error) |
ONE-BLOCK | ReadResponse ::= (data-block-result) | Read.response (Data_Block_Result) with Last_Block = FALSE |
LAST-BLOCK | ReadResponse ::= (data-block-result) | Read.response (Data_Block_Result) with Last_Block = TRUE |
WITH-LIST | ReadResponse ::= ({data | data-access-error}) | Read.response ({Data | Data_Access_Error}) |
From ACTION.request of type | To Read.request | SN APDU |
---|---|---|
NORMAL | Read.request (Variable_Access_Specification) Variable_Access_Specification = Parameterized_Access;with Variable_Name = method reference, Selector = 0, Parameter = method invocation parameter or null-data | ReadRequest ::= (parameterized-access) |
NEXT | Read.request (Variable_Access_Specification) Variable_Access_Specification = Block_Number_Access; | ReadRequest :: = (block-number-access) |
FIRST-BLOCK | Read.request (Variable_Access_Specification) Variable_Access_Specification = Read_Data_Block_Access;with Last_Block = FALSE, Block_Number = 1,Raw_Data = one part of the method reference(s) and method invocation parameter | ReadRequest ::= (read-data-block-access) |
ONE-BLOCK | Read.request (Variable_Access_Specification) Variable_Access_Specification = Read_Data_Block_Access;with Last_Block = FALSE,Block_Number = next number, Raw_Data = as above | ReadRequest ::= (read-data-block-access) |
LAST-BLOCK | Read.request (Variable_Access_Specification) Variable_Access_Specification = Read_Data_Block_Access;with Last_Block = TRUE,Block_Number = next number, Raw_Data = as above | ReadRequest ::= (read-data-block-access) |
WITH-LIST | Read.request ({Variable_Access_Specification}) Variable_Access_Specification = Parameterized_Access;with Variable_Name = method reference, Selector = 0,Parameter = method invocation parameter or null-data | ReadRequest ::= ({parameterized-access}) |
WITH-LIST-AND-FIRST- BLOCK | Read.request (Variable_Access_Specification) Variable_Access_Specification = Read_Data_Block_Access;with Last_Block = FALSE, Block_Number = 1, Raw_Data = as above | ReadRequest ::= (read-data-block-access) |
To ACTION.confirm | SN APDU | From Read.response |
NORMAL | ReadResponse ::= (data | data-access-error) | Read.response (Read_Result) Read_Result =Data I Data_Access_Error; |
ONE-BLOCK | ReadResponse ::= (data-block-result) | Read.response (Read_Result) Read_Result = Data_Block_Result; with Last_Block = FALSE |
LAST-BLOCK | ReadResponse ::= (data-block-result) | Read.response (Read_Result) Read_result = Data_Block_Result; with Last_Block = TRUE |
NEXT | ReadResponse ::= (block-number) | Read.confirm (Read_Result) Read_Result = Block_Number; |
WITH-LIST | ReadResponse ::= ({data I data-access-error}) | Read.response ({Read_Result}) Read_Result =Data I Data_Access_Error; |
图104显示了用于读取单个属性值的Read服务的MSC。
图105显示了用于调用单个Method的Read服务的MSC。
图106显示了用于读取单个属性的Read服务的MSC,结果使用service-specific block transfer机制在三个块中返回。或者,可以使用general block transfer机制。

- 准备和传输长数据的过程本质上与GET和ACTION服务的过程相同。
- 如果Read服务用于读取COSEM对象属性的值,则Data_Block_Result构造的Raw_Data元素携带Read_Result列表的一部分;
- 如果Read服务用于调用COSEM对象方法,并且必须发送长方法调用参数,则Read_Data_Block_Access构造的Raw_Data元素携带部分方法引用和方法调用参数。如果返回长方法调用响应,则Data_Block_Result构造的Raw_Data元素携带方法调用响应的一部分。
如果发生错误,服务器应该返回一个Read.response服务原语,Data_Access_Error携带适当的诊断信息;例如data-block-number-invalid。
9.4.6.10 Protocol for the Write service
- 如9.3.15所述,当服务器使用SN referencing时使用Write服务,或者写COSEM对象属性,或者在没有返回参数时调用Method:
- 在第一种情况下,SET.request服务原语映射为Write.request原语和Write.confirm原语映射为SET.confirm原语。其对应关系及对应的SN apdu如表83所示;
- 在第二种情况下,ACTION.request服务原语映射为Write.request原语和Write.response原语映射为ACTION.confirm原语。其对应关系及对应的SN apdu如表84所示。
From SET.request of type | To Write.request | SN APDU |
---|---|---|
NORMAL | Write.request (Variable_Access_Specification, Data) Variable_Access_Specification =Variable_Name|Parameterized_Access; | WriteRequest ::= (variable-name|parameterized-access, data) |
FIRST-BLOCK | Write.request (Variable_Access_Specification, Data) Variable_Access_Specification = Write_Data_Block_Access;withLast_Block = FALSE, Block_Number = 1,Data = raw-data, carrying the encoded form of the attribute reference(s) and write data. | WriteRequest ::=(write-data-block-access, data) |
ONE-BLOCK | Write.request (Variable_Access_Specification, Data) Variable_Access_Specification = Write_Data_Block_Access;withLast_Block = FALSE,Block_Number = next number,Data = as above | WriteRequest ::=(write-data-block-access, data) |
LAST-BLOCK | Write.request (Variable_Access_Specification, Data) Variable_Access_Specification = Write_Data_Block_Access;withLast_Block = TRUE,Block_Number = next number,Data = as above | WriteRequest ::=(write-data-block-access, data) |
WITH-LIST | Write.request ({Variable_Access_Specification}, {Data}) Variable_Access_Specification =Variable_Name|Parameterized_Access; | WriteRequest ::=({variable-name|parameterized-access},{data}) |
FIRST-BLOCK-WITH- LIST | Write.request (Variable_Access_Specification, Data) Variable_Access_Specification = Write_Data_Block_Access;withLast_Block = FALSE, Block_Number = 1 Data =as above | WriteRequest ::=(write-data-block-access, data) |
To SET.confirm of type | SN APDU | From Write.response |
NORMAL | WriteResponse ::=(success|data-access-error) | Write.response (Write_Result) Write_Result =Success|Data_Access_Error; |
ACK-BLOCK | WriteResponse ::= (block-number) | Write.response (Write_Result) Write_Result = Block_Number; |
LAST-BLOCK | WriteResponse ::=(success|data-access-error) | Write.response (Write_Result) Write_Result =Success|Data_Access_Error; |
WITH-LIST | WriteResponse ::=({success|data-access-error}) | Write.response ({Write_Result}) Write_Result =Success|Data_Access_Error; |
LAST-BLOCK-WITH-LIST | WriteResponse ::=({success|data-access-error}) | Write.response ({Write_Result}) Write_Result =Success|Data_Access_Error; |
From ACTION.request of type | To Write.request | SN APDU |
---|---|---|
NORMAL | Write.request (Variable_Access_Specification, Data )Variable_Access_Specification = Variable_Name;Data = method invocation parameters or null-data | WriteRequest ::= (variable-name, data) |
FIRST-BLOCK | Write.request (Variable_Access_Specification, Data) Variable_Access_Specification = Write_Data_Block_Access;withLast_Block = FALSE, Block_Number = 1,Data = raw-data, carrying the encoded form of the method reference(s) and method invocation parameters; | WriteRequest ::= (write-data-block-access, data) |
ONE-BLOCK | Write.request (Variable_Access_Specification, Data) Variable_Access_Specification = Write_Data_Block_Access;withLast_Block = FALSE,Block_Number = next number,Data = as above | WriteRequest ::= (write-data-block-access, data) |
LAST-BLOCK | Write.request (Variable_Access_Specification, Data) Variable_Access_Specification = Write_Data_Block_Access;withLast_Block = TRUE,Block_Number = next number,Data = as above | WriteRequest ::= (write-data-block-access, data) |
WITH-LIST | Write.request ({Variable_Access_Specification}, {Data}) Variable_Access_Specification = Variable_Name;Data = method invocation parameters or null data | WriteRequest ::= ({variable-name}, {data}) |
WITH-LIST-AND-FIRST- BLOCK | Write.request (Variable_Access_Specification, Data) Variable_Access_Specification = Write_Data_Block_Access;withLast_Block = FALSE, Block_Number = 1,Data = as with first block | WriteRequest ::= (write-data-block-access, data) |
To ACTION.confirm | SN APDU | From Write.response |
NORMAL | WriteResponse ::=(success|data-access-error) | Write.response (Write_Result) Write_Result =Success|Data_Access_Error |
NEXT | WriteResponse ::= (block-number) | Write.response (Block_Number) |
WITH-LIST | WriteResponse ::=({success I data-access-error}) | Write.response ({Write_Result}) Write_Result =Success|Data_Access_Error |
图107显示了Write服务的MSC,在成功的情况下,该服务用于写入单个属性的值。
图108显示了在成功的情况下,用于调用单个方法的Write服务的MSC。
图109显示了Write服务的MSC,用于写入单个属性,并使用service-specific block transfer机制在三个块中返回结果。或者,可以使用general block transfer机制。
准备和传输长数据的过程本质上与SET和ACTION服务的过程相同。
如果发生错误,服务器应该返回Write。响应服务原语,Data_Access_Error携带适当的诊断信息,例如data-block-number-invalid。
9.4.6.11 Protocol for the UnconfirmedWrite service
只有在已经建立了AA时才能调用此服务。根据通信配置文件,可以使用支持协议层的面向连接或无连接数据服务来传输与请求相对应的APDU。
- 如9.3.16所述,UnconfirmedWrite服务可用于写入COSEM对象属性,或在没有返回参数时调用Method:
- 在第一种情况下,SET.request服务原语映射到UnconfirmedWrite.request原语。其对应关系及对应的SN apdu如表85所示;
- 在第二种情况下,ACTION.request服务原语映射到UnconfirmedWrite.request原语。其对应关系及对应的SN apdu如表86所示。
From SET.request of type | To UnconfirmedWrite.request | SN APDU |
---|---|---|
NORMAL | UnconfirmedWrite.request (Variable_Access_Specification, Data) Variable_Access_Specification =Variable_Name I Parameterized_Access; | UnconfirmedWriteRequest ::= (variable-name I parameterized-access, data) |
WITH-LIST | UnconfirmedWrite.request ({Variable_Access_Specification}, {Data}) Variable_Access_Specification =Variable_Name I Parameterized_Access; | UnconfirmedWriteRequest ::= ({variable-name I parameterized-access},{data}) |
From ACTION .request of type | To UnconfirmedWrite.request | SN APDU |
---|---|---|
NORMAL | UnconfirmedWrite.request (Variable_Access_Specification, Data) Variable_Access_Specification = Variable_Name;Data = method invocation parameters or null data | UnconfirmedWriteRequest ::= (variable-name, data) |
WITH-LIST | UnconfirmedWrite.request ({Variable_Access_Specification}, {Data}) Variable_Access_Specification = Variable_Name;Data = as above | UnconfirmedWriteRequest ::= ({variable-name}, {data}) |
图110显示了Write服务的MSC,在成功的情况下,该服务用于写入单个属性的值
当服务参数较长时,可采用general block transfer机制。
9.4.6.12 Protocol for the InformationReport service
在9.3.17中指定的InformationReport服务的协议本质上与9.4.6.6中指定的EventNotification服务的协议相同。
与EventNotification服务不同,InformationReport服务不包含可选的Application_Addresses参数,因此信息报告总是由服务器管理逻辑设备发送给客户端管理AP。
在调用InformationReport时。请求服务时,服务器AP构建一个informationReportRequest APDU。该APDU在第一次可用的机会中以非请求的方式,使用较低层的数据服务,从管理逻辑设备的SAP发送到客户端管理AP的SAP。
发送此APDU的可能性取决于通信配置文件和较低层的连接状态。因此,在10中进一步讨论了InformationReport服务的协议。
InformationReport服务可以携带多个属性名及其内容。另一方面,9.3.9中指定的EventNotification服务只包含一个属性引用。
因此,当informationReportRequest APDU包含多个属性时,它必须映射到几个EventNotification.ind服务,如表87所示。
EventNotification.ind (one or more) | InformationReport.ind |
---|---|
Time (optional) | Current-time (optional) |
COSEM_Class_Id, COSEM_Object_Instance_Id, COSEM_Object_Attribute_Id | Variable_Name {Variable_Name} |
Attribute_Value | Data {Data} |
9.4.6.13 Protocol of general block transfer mechanism
通用块传输(GBT)机制可用于携带任何xDLMS服务原语,当服务参数很长时,即它们的编码形式长于协商的最大接收PDU大小。在这种情况下,AL使用一个或多个通用块传输(GBT) xDLMS apdu来传输这种长消息。
服务原语调用可以是完整的,包括所有的服务参数,也可以是部分的,只包括一部分的服务参数。使用完整的或部分的服务调用留给实现。
- 从AP接收到.request / .response服务原语后,AL:
- 构建携带服务原语的APDU;
- 当需要加密时,它应用Security_Options所要求的保护,并构建适当的加密APDU;
- 当生成的APDU大于协商的最大APDU大小时,则AL使用GBT机制在几个GBT APDU中发送完整的消息。
但是,部分调用和发送的GBT apdu之间没有直接关系。AL可以使用完整或部分服务调用来应用保护。
- 从远程方接收GBT apdu后,AL:
- 将接收到的GBT apdu的块数据字段组装在一起;
- 当产生的完整APDU被加密时,它会检查并移除保护;
- 它调用适当的服务原语,传递额外的Security_Status, General_Block_Transfer_Parameters和Protection_Element。
但是,接收到的GBT apdu与部分服务调用之间没有直接关系。AL可以验证和移除处理GBT APDU或处理完整、组装的APDU的保护。
另请参见图88。
消息交换可以在有
或没有
使用GBT的情况下启动。但是,如果一方使用GBT发送请求或响应,另一方应遵循。然后,双方继续使用GBT,直到结束(即直到收到完整的答复)。

服务原语可以由完整的或部分的服务调用组成。携带服务原语编码形式的未保护或受保护APDU可以由一个或多个General-Block-Transfer APDUs组成。
Note: apdu加密保护的应用、检查和解除与GBT进程无关。这里包含它是为了完整。
块的流由AL管理,它考虑了从本地AP传递给AL的GBT参数(参见9.3.5)和从远程AL接收的GBT apdu的字段(参见图111)。
各种服务调用类型——COMPLETE、FIRST-PART、ONE-PART或LAST-PART——以及这些调用,服务参数,加密apdu的字段和通用块传输(GBT) apdu之间的关系如图111所示。
Block_Transfer_Streaming (BTS)参数由AP传递给AL,以表明AL可以在流中发送块,即无需等待远程方接收到的每个块的确认。该参数不包含在APDU中。
Block_Transfer_Window(BTW)参数指示支持的流窗口的大小,即可以接收的最大块数。另一方的Block_Transfer_Window参数可以是各方已知的优先级。但是,窗口大小由AL管理:它可以使用较低的值,例如在丢失块恢复期间。
图111中Block_Transfer_Window参数与APDU的window字段之间的关系用虚线表示。
对于未经确认的服务,Block_Transfer_Streaming参数设置为FALSE, Block_Transfer_Window设置为0。这向AL表明,它应根据需要以尽可能多的GBT apdu发送整个服务原语的编码形式,而不必等待发送的块的确认。
- GBT APDU字段的使用说明如下:
- 最后块(LB)位表示该块是否为最后一块(LB = 1)或不是(LB = 0);
- 流比特表示流是正在进行(STR = 1)还是已完成(STR = 0)。当流完成时,远程方应确认接收到的数据块。当Block_Transfer_Streaming参数设置为FALSE时,流位也应设置为0;
- 窗口字段表示发送APDU的一方可以接收的块的数量。它的最大值等于AP传递给AL的Block_Transfer_Window参数。注意,在丢失的块恢复过程中,AL可以使用较小的值。在GBT apdu携带未确认业务的情况下(BTS = FALSE, BTW = 0;如上所示),则窗口值为0,表示不需要确认GBT apdu(因此无法恢复丢失的块);
- block-number (BN)字段表示发送的块的编号。发送的第一个区块block-number = 1。每发送一个GBT APDU,即使block-data (BD)为空,Block-number也会增加。然而,在丢失的块恢复期间,可以重复一个块号;
- BNA (block-number-acknowledge)字段表示被承认的块编号。如果没有块丢失,则等于接收到的最后一个块的数量。但是,如果丢失一个或多个块,则应等于没有丢失块的块数;
- block-data (BD)字段携带使用GBT机制发送的xDLMS APDU的一部分。
如果一方没有数据块可发送,则将APDU的最后一个数据块位设置为1,将流码位设置为0。
通过图112、图113、图114、图115、图116、图117、图118进一步说明GBT机制的协议。在这些示例中,假设双方都支持GBT,并且需要6个块来传输完整的响应或请求(DataNotification示例除外,它需要4个块)。
注2:在这些示例中,没有使用service-specific block transfer机制。
- 数字上使用的缩写:
- BTS: Block_Transfer_Streaming, BTW: Block_Transfer_Window;
- GBT:general-block-transfer APDU;
- LB:最后一块;
- STR:流媒体;
- BN:块号,BNA:已确认的块号;
- BD(APDU):包含一个APDU块的块数据。

- 图112显示了使用GBT的GET服务。在接收到第一个GBT APDU之后,客户端通知服务器它支持流。服务器切换到流媒体。流程如下:
- 客户端AP调用GET.request NORMAL服务原语(没有附加的服务参数)。客户端AL以Get-Request-Normal APDU方式发送请求;
- GET.response服务参数很长,因此服务器调用GET.response NORMAL 服务原语(带有附加服务参数)Invocation_Type = COMPLETE, BTS = 1, BTW = 1意味着服务器允许发送块流,但它不接受来自客户端的块流。服务器AL发送一个GBT APDU,包含响应的第一个块;
- 客户端调用GET.confirm NORMAL服务原语,Invocation_Type = FIRST-PART, BTW = 1。Service_Parameters为空。通过这种方式,它通知AP来自服务器的响应很长;
- 客户端AP调用GET.request NORMAL服务原语,使用Invocation_Type = COMPLETE, BTS = 0, BTW = 3来发布其接收块流的能力。注意Service_Parameters是空的,因为它们已经在第一个GET中传递了。请求正常服务调用。客户端AL发送一个GBT APDU。由于客户端没有块要发送,APDU中的最后一个块位设置为1,流位设置为0;
- 服务器发送2nd(STR = 1, BN = 2),3rd(STR = 1, BN = 3)和4th(STR = 0, BN = 4)块;
- 客户端AL发送一个GBT APDU,以确认接收到2nd、3rd和4th(LB = 1,STR = 0, W = 3, BNA = 4);
- 服务器AL发送5th(STR =1, BN = 5)和6th(LB =1, STR = 0, BN = 6);
最后一块未确认。然而,当丢失时,它是可以恢复的。见图115
。 - 客户端调用GET.confirm NORMAL服务原语(Invocation_Type = LAST-PART)。服务参数包括对GET.request的完整响应。

- 图113显示了一个使用GBT的GET服务,在服务器端使用部分服务调用和流。客户端在第一个请求中宣传其流媒体功能(BTW = 3;BTW > 1表示可以接收块流)。服务器在第二个流中发送的4th块丢失并被恢复。流程如下:
- 客户端AP调用GET.request NORMAL服务原语,其中Invocation_Type = COMPLETE, BTS = 0, BTW = 3。客户端AL发送一个STR = 0, Window = 3的GBT APDU。服务器AL调用GET.indication NORMAL服务原语,Invocation_Type = COMPLETE, BTW = 3;
- 服务器AP调用GET.response NORMAL服务原语,Invocation_Type = FIRST-PART, BTS = 1, BTW = 1。Service_Parameters包括响应的第一部分。服务器AL发送1st,2nd,3rd区块;
- 客户端AL发送GBT APDU以确认三个块的接收。服务器AP调用具有Invocation_Type=LAST-PART的GET.response NORMAL服务原语。Service_Parameters包括响应的第二部分,即最后一部分。服务器AL发送4th,5th,6th。然而,4th区块丢失;
- 客户端AL通过发送GBT APDU确认接收到3rd块(STR = 0, window = 1, BNA = 3)来指示第4th尚未收到。注意,客户端AL将窗口大小降至1,以表示只需要重新发送一个块;
- 服务器再次发送4th(LB = 1, STR = 0, BN = 4, BNA = 3);
- 由于客户端现在已经接收到所有块,它调用一个GET.confirm NORMAL服务原语,Invocation_Type=COMPLETE,BTW=1。此调用的Service_Parameters包含对GET.request的完整响应。

- 图114显示了一个与图113基本相同的场景,只是4th和5th区块丢失和恢复。过程如下:
- 客户端接收6th个块(LB=1,STR=0,BN=6,BNA=2);
- 客户端通过发送W=2、BNA=3的GBT APDU来指示4th和5th个块已经丢失,即意味着直到3rd块都没有丢失块,但丢失了两个块,并且服务器可以使用流发送这两个块;
- 服务器随后发送丢失(未确认)的4th块(LB=0,STR=1,BN=4)和5th块(LB=1,STR=0,BN=5)。请注意,LB已设置为1;
- 客户端现在已经接收到每个块。然后它调用一个GET.confirm NORMAL服务原语(Invocation_Type=COMPLETE,BTW=1)。Service_Parameters包括对GET.request的完整响应的参数。

- 图115显示了第二个流中发送的最后一个块丢失并被恢复的场景。过程如下:
- 客户端接收GBT APDU携带的5th个块(LB=0,STR=1,BN=5);
- 由于这不是最后一个块,在特定于实现的超时之后,客户端发送GBT APDU(LB=1,STR=0,BN=3,BNA=5);
- 服务器随后发送由GBT APDU携带的丢失(未确认)的6th块(LB=1,STR=0,W=1,BN=6和BNA=3);
- 当客户端收到此APDU时,它会调用一个GET.confirm NORMAL服务原语(Invocation_Type=COMPLETE,BTW=1)。Service_Parameters包括对GET.request的完整响应的参数。

- 图116显示了一个带有GBT和流的SET服务。客户端发送的3rd区块丢失并恢复。流程如下:
- 客户端AP调用SET.request NORMAL服务原语(Invocation_Type=FIRSTPART,BTS=1,BTW=1)。Service_Parameters包括SET.request的第一部分。客户端AL发送第一个块只是因为它不知道服务器支持的流window size;
- 服务器AL调用一个SET.indication NORMAL服务原语(Invocation_Type=FIRSTPART,BTW=1)。Service_Parameters包括SET.request的参数的第一部分;
- 服务器AP以SET.response NORMAL服务原语进行响应,Invocation_Type=FIRST-PART,BTS=0,BTW=3。Service_Parameters为空。服务器AL发送LB=1,STR=0,Window=3的GBT APDU;块数据为空。由此,客户端知道服务器可以接收块流,并且window size=3。因此,它在流中发送2nd,3rd,4th。然而,3rd区块丢失;
- 服务器通过确认接收到第二个块并将window size降为1 (LB = 1, STR = 0, W = 1, BN = 2, BNA = 2)来指示3rd丢失。客户端再次发送3rd块(LB = 0, STR = 0, BN = 3, BNA = 2);
- 服务器调用Invocation_Type=ONEPART的SET.indication NORMAL服务原语。服务器AL确认直到第4个块(LB=1,STR=0,W=3,BNA=4)的块的接收。请注意,window size已再次提高到3;
- 客户端使用流发送5th个和6th个块;
- 当服务器AL接收到6th个,最后一个块时,它调用调用类型为Last-PART的SET.indication NORMAL服务原语。Service_Parameters包括SET.request的最后一部分参数;
- 服务器AP调用SET.request NORMAL服务原语,Invocation_Type=LASTPART,service_Parameters包含设置操作的结果。这是由服务器AL在GBT APDU中发送的。客户端AL调用具有Invocation_Type=LAST-PART的SET.conf NORMAL服务原语。Service_Parameters包括设置操作的结果。

- 图117显示了一个带有部分服务调用、双向块传输和流的ACTION-WITH-LIST服务。双方都先验地知道另一方支持window size= 3的流。服务器发送的第一个块丢失并恢复。流程如下:
- 客户端调用和ACTION.request类型为WITH-LIST服务原语,Invocation_type=COMPLETE,BTS=1,BTW=3。客户端AL将携带该请求的一部分的前三个块发送到服务器。服务器AL调用类型WITH-LIST服务原语的ACTION.indication(Invocation_type=FIRST-PART,BTW=3)。服务参数包含请求的第一部分;
- 服务器AP处理此请求,并具有可用的响应的第一部分。它调用类型为WITH-LIST的ACTION.response服务原语(Invocation_type=FIRST-PART,BTS=1,BTW=3)。服务器AL使用流传输在三个块中发送该消息。然而,第一个区块丢失;
- 客户端AL通过不确认接收到的任何块,要求服务器再次发送丢失的第一个块。它还发送它的4th块(LB=0,STR=0,W=1,BN=4,BNA=0)。注意,客户端AL已经将window size降低到1;
- 服务器AL调用类型WITH-LIST服务原语的ACTION.indication,其中INVOCIATION_type=ONE-PART。Service_Parameters包含请求的一部分;
- 服务器发送丢失的第一个块,并确认从客户端接收的4th块(BN=1,BNA=4);
- 客户端AL调用WITH-LIST服务原语类型的ACTION.conf,并带有附加参数:Invocation_type=FIRST-PART,BTW=3。Service_Parameters包括来自服务器的响应的一部分;
- 客户端AL发送5th个和6th个,最后一个块。window size再次提高到3;
- 服务器AL调用WITH-LIST服务原语类型的ACTION.indication,Invocation_type=LAST-PART,service_Parameters包含ACTION.request的最后一部分;
- 服务器AP对此进行处理,并调用类型为WITH-LIST的ACTION.response服务原语,其中Invocation_type=LAST-PART;Service_ Parameters包含响应的剩余部分。这是使用流式传输分三个块发送给客户端的;
- 客户端AL调用WITH-LIST服务原语类型的ACTION.conf,Invocation_type=LAST-PART。Service_Parameters包括来自服务器的响应的最后一部分。

- 图118显示了一个带有GBT的DataNotification服务,在服务器端有部分服务调用。过程如下:
- 服务器AP调用DataNotification.request服务原语,Invocation_Type=FIRST-PART,BTS=0,BTW=0。Service_Parameters包括DataNotification.request的一部分;
- 服务器AL向客户端发送GBT APDU。块的接收未得到确认,块恢复不可用;
- 当客户端AL接收到最后一个块时,它将块数据组装在一起,并调用Invocation_Type=COMPLETE、BTW=0的DataNotification.indication服务原语。Service_Parameters包括完整的DataNotification服务参数。
中止GBT过程
客户端或服务器可能想要中止GBT进程。为此,它应发送LB=1、STR=0、BN=0和BNA=0的GBT APDU。如果一方确认接收到另一方尚未发送的块,则块传输过程也应中止。
无法使用DataNotification中止GBT。
9.4.6.14 Protocol of exception mechanism
- xDLMS服务请求可能会在无法处理该请求时导致异常,因此无法发回与该请求相对应的响应。在这种情况下,在SN referencing的情况下,服务器可选地使用confirmedServiceError APDU,在LN referencing的情况中使用异常响应APDU。
- confirmedServiceError APDU:这是一个APDU,如果确认的service.request调用失败,并且相应的.response原语无法返回,则服务器可以发送该APDU来提供特定于服务的诊断信息。它可以与InitiateRequest、Read和Write服务一起使用;
- the exception-response APDU:这是一个APDU,当与使用LN referencing的请求相对应的.response原语无法发送回时,服务器可以发送该APDU。它可以和GET、SET、ACTION和ACCESS服务一起使用;
表88中规定了使用xDLMS异常机制的条件。
Request processing condition | LN referencing response APDU | SN referencing response APDU |
---|---|---|
通信未建立 | exception-response(state-error = service-not-allowed, service-error = operation-not-possible) | confirmedServiceError(read or write, vde-state-error = no-dlms-context) |
Request APDU size>server-max- receive-pdu-size | exception-response(state-error = service-not-allowed, service-error = pdu-too-long) | confirmedServiceError(read or write, service = pdu-size) |
由于调用计数器错误,未验证或删除保护 | exception-response(state-error = service-not-allowed, service-error = invocation-counter- error)value = lowest acceptable value of invocation counter | confirmedServiceError (read or write, application-reference = deciphering-error) |
由于解密错误,未验证或删除保护 | exception-response(state-error = service-not-allowed, service-error = deciphering-error) | confirmedServiceError (read or write, application-reference = deciphering-error) |
请求格式不正确 | exception-response(state-error = service-not-known, service-error = operation-not-possible) | confirmedServiceError(read or write, definition = other) |
协商一致性不支持请求 | exception-response(state-error = service-not-allowed, service-error = service-not-supported) | confirmedServiceError(read or write, service = service- unsupported) |
s9.5 Abstract syntax of COSEM PDUs
COSEM pdu的抽象语法在此子条款中使用ASN.1指定。参见ISO/IEC 8824:2008。
10.4.9中指定了CIASE apdu
COSEMpdu DEFINITIONS ::= BEGIN
ACSE-APDU ::= CHOICE
{
aarq AARQ-apdu,
aare AARE-apdu,
rlrq RLRQ-apdu, -- OPTIONAL
rlre RLRE-apdu -- OPTIONAL
}
XDLMS-APDU ::= CHOICE
{
-- standardised xDLMS pdus used in DLMS/COSEM
-- with no ciphering
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,
-- data-notification
data-notification [15] IMPLICIT Data-Notification,
unconfirmedWriteRequest [22] IMPLICIT UnconfirmedWriteRequest,
informationReportRequest [24] IMPLICIT InformationReportRequest,
-- 每个经过加密的xDLMS APDU的APDU标签表明未加密的APDU的类型,以及使用的是global key还是dedicated key。密钥的类型由security header携带,在删除加密和/或验证身份验证标记后,恢复原始APDU及其APDU tag。因此,经过加密后的APDU标签会携带冗余信息,但为了保持一致性,APDU标签会被保留。
-- with global ciphering
glo-initiateRequest [33] IMPLICIT OCTET STRING,
glo-readRequest [37] IMPLICIT OCTET STRING,
glo-writeRequest [38] IMPLICIT OCTET STRING,
glo-initiateResponse [40] IMPLICIT OCTET STRING,
glo-readResponse [44] IMPLICIT OCTET STRING,
glo-writeResponse [45] IMPLICIT OCTET STRING,
glo-confirmedServiceError [46] IMPLICIT OCTET STRING,
glo-unconfirmedWriteRequest [54] IMPLICIT OCTET STRING,
glo-informationReportRequest [56] IMPLICIT OCTET STRING,
-- with dedicated ciphering
ded-initiateRequest [65] IMPLICIT OCTET STRING,
ded-readRequest [69] IMPLICIT OCTET STRING,
ded-writeRequest [70] IMPLICIT OCTET STRING,
ded-initiateResponse [72] IMPLICIT OCTET STRING,
ded-readResponse [76] IMPLICIT OCTET STRING,
ded-writeResponse [77] IMPLICIT OCTET STRING,
ded-confirmedServiceError [78] IMPLICIT OCTET STRING,
ded-unconfirmedWriteRequest [86] IMPLICIT OCTET STRING,
ded-informationReportRequest [88] IMPLICIT OCTET STRING,
-- xDLMS APDUs used with LN referencing
-- with no ciphering
get-request [192] IMPLICIT Get-Request,
set-request [193] IMPLICIT Set-Request,
event-notification-request [194] IMPLICIT EventNotificationRequest,
action-request [195] IMPLICIT Action-Request,
get-response [196] IMPLICIT Get-Response,
set-response [197] IMPLICIT Set-Response,
action-response [199] IMPLICIT Action-Response,
-- with global ciphering
glo-get-request [200] IMPLICIT OCTET STRING,
glo-set-request [201] IMPLICIT OCTET STRING,
glo-event-notification-request [202] IMPLICIT OCTET STRING,
glo-action-request [203] IMPLICIT OCTET STRING,
glo-get-response [204] IMPLICIT OCTET STRING,
glo-set-response [205] IMPLICIT OCTET STRING,
glo-action-response [207] IMPLICIT OCTET STRING,
-- with dedicated ciphering
ded-get-request [208] IMPLICIT OCTET STRING,
ded-set-request [209] IMPLICIT OCTET STRING,
ded-event-notification-request [210] IMPLICIT OCTET STRING,
ded-actionRequest [211] IMPLICIT OCTET STRING,
ded-get-response [212] IMPLICIT OCTET STRING,
ded-set-response [213] IMPLICIT OCTET STRING,
ded-action-response [215] IMPLICIT OCTET STRING,
-- the exception response pdu
exception-response [216] IMPLICIT ExceptionResponse,
-- access
access-request [217] IMPLICIT Access-Request,
access-response [218] IMPLICIT Access-Response,
-- general APDUs
general-glo-ciphering [219] IMPLICIT General-Glo-Ciphering,
general-ded-ciphering [220] IMPLICIT General-Ded-Ciphering,
general-ciphering [221] IMPLICIT General-Ciphering,
general-signing [223] IMPLICIT General-Signing,
general-block-transfer [224] IMPLICIT General-Block-Transfer
-- The tags 230 and 231 are reserved for DLMS Gateway
-- reserved [230]
-- reserved [231]
}
AARQ-apdu ::= [APPLICATION 0] IMPLICIT SEQUENCE
{
-- [APPLICATION 0] == [ 60H ] = [ 96 ]
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,
-- 如果只使用kernel,则不应出现以下字段。
sender-acse-requirements [10] IMPLICIT ACSE-requirements OPTIONAL,
-- 以下字段只有在选择authentication功能单元时才会出现。
mechanism-name [11] IMPLICIT Mechanism-name OPTIONAL,
-- 以下字段只有在选择authentication功能单元时才会出现。
calling-authentication-value [12] EXPLICIT Authentication-value OPTIONAL,
implementation-information [29] IMPLICIT Implementation-data OPTIONAL,
user-information [30] EXPLICIT Association-information OPTIONAL
}
-- user-information字段必须携带一个用A-XDR编码的InitiateRequest APDU,然后用BER编码得到的OCTET STRING。
AARE-apdu ::= [APPLICATION 1] IMPLICIT SEQUENCE
{
-- [APPLICATION 1] == [ 61H ] = [ 97 ]
protocol-version [0] IMPLICIT BIT STRING {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,
-- 如果只使用kernel,则不应出现以下字段。
responder-acse-requirements [8] IMPLICIT ACSE-requirements OPTIONAL,
-- 以下字段只有在选择authentication功能单元时才会出现。
mechanism-name [9] IMPLICIT Mechanism-name OPTIONAL,
-- 以下字段只有在选择authentication功能单元时才会出现。
responding-authentication-value [10] EXPLICIT Authentication-value OPTIONAL,
implementation-information [29] IMPLICIT Implementation-data OPTIONAL,
user-information [30] EXPLICIT Association-information OPTIONAL
}
--user-information应该携带一个InitiateResponse(或者,当提议的xDLMS上下文不被服务器接受时,一个ConfirmedServiceError)在A-XDR中编码的APDU,然后在BER中编码产生的OCTET STRING。
RLRQ-apdu ::= [APPLICATION 2] IMPLICIT SEQUENCE
{
-- [APPLICATION 2] == [ 62H ] = [ 98 ]
reason [0] IMPLICIT Release-request-reason OPTIONAL,
user-information [30] EXPLICIT Association-information OPTIONAL
}
RLRE-apdu ::= [APPLICATION 3] IMPLICIT SEQUENCE
{
-- [APPLICATION 3] == [ 63H ] = [ 99 ]
reason [0] IMPLICIT Release-response-reason OPTIONAL,
user-information [30] EXPLICIT Association-information OPTIONAL
}
-- RLRQ / RLRE APDU的user-information字段可能携带一个用A-XDR编码的InitiateRequest APDU,然后在BER中编码得到的OCTET STRING,当要释放的AA使用加密时。
-- 在ACSE apdu的字段中使用的类型,按其出现的顺序
Application-context-name ::= OBJECT IDENTIFIER
AP-title ::= OCTET STRING
AE-qualifier ::= OCTET STRING
AP-invocation-identifier ::= INTEGER
AE-invocation-identifier ::= INTEGER
ACSE-requirements ::= BIT STRING {authentication(0)}
Mechanism-name ::= OBJECT IDENTIFIER
Authentication-value ::= CHOICE
{
charstring [0] IMPLICIT GraphicString,
bitstring [1] IMPLICIT BIT STRING
}
Implementation-data ::= GraphicString
Association-information ::= OCTET STRING
Association-result ::= INTEGER
{
accepted (0),
rejected-permanent (1),
rejected-transient (2)
}
Associate-source-diagnostic ::= CHOICE
{
acse-service-user [1] INTEGER
{
null (0),
no-reason-given (1),
application-context-name-not-supported (2),
calling-AP-title-not-recognized (3),
calling-AP-invocation-identifier-not-recognized (4),
calling-AE-qualifier-not-recognized (5),
calling-AE-invocation-identifier-not-recognized (6),
called-AP-title-not-recognized (7),
called-AP-invocation-identifier-not-recognized (8),
called-AE-qualifier-not-recognized (9),
called-AE-invocation-identifier-not-recognized (10),
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)
}
}
Release-request-reason ::= INTEGER
{
normal (0),
urgent (1),
user-defined (30)
}
Release-response-reason ::= INTEGER
{
normal (0),
not-finished (1),
user-defined (30)
}
-- Useful types
Integer8 ::= INTEGER(-128..127)
Integer16 ::= INTEGER(-32768..32767)
Integer32 ::= INTEGER(-2147483648..2147483647)
Integer64 ::= INTEGER(-9223372036854775808..9223372036854775807)
Unsigned8 ::= INTEGER(0..255)
Unsigned16 ::= INTEGER(0..65535)
Unsigned32 ::= INTEGER(0..4294967295)
Unsigned64 ::= INTEGER(0..18446744073709551615)
-- 在协商建立期间使用的xDLMS apdu
InitiateRequest ::= SEQUENCE
{
-- shall not be encoded in DLMS without ciphering
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, -- Shall be encoded in BER
client-max-receive-pdu-size Unsigned16
}
-- 在DLMS/COSEM中,不使用quality-of-service参数。任何价值均可接受。
--一致性字段应以BER编码。参见IEC 61334-6例1。
InitiateResponse ::= SEQUENCE
{
negotiated-quality-of-service [0] IMPLICIT Integer8 OPTIONAL,
negotiated-dlms-version-number Unsigned8,
negotiated-conformance Conformance, -- Shall be encoded in BER
server-max-receive-pdu-size Unsigned16,
vaa-name ObjectName
}
-- 在LN referencing的情况下,vaa-name的值为0x0007
-- 在SN referencing的情况下,vaa-name的值是当前关联对象的基名0xFA00
-- Conformance Block
-- SIZE constrained BIT STRING is extension of ASN.1 notation
Conformance ::= [APPLICATION 31] IMPLICIT BIT STRING
{
-- 当相应的服务或功能可用时,设置该位
reserved-zero (0),
-- 一般保护服务的实际列表取决于安全套件
general-protection (1),
general-block-transfer (2),
read (3),
write (4),
unconfirmed-write (5),
reserved-six (6),
reserved-seven (7),
attribute0-supported-with-set (8),
priority-mgmt-supported (9),
attribute0-supported-with-get (10),
block-transfer-with-get-or-read (11),
block-transfer-with-set-or-write (12),
block-transfer-with-action (13),
multiple-references (14),
information-report (15),
data-notification (16),
access (17),
parameterized-access (18),
get (19),
set (20),
selective-access (21),
event-notification (22),
action (23)
}
ObjectName ::= Integer16
-- 对于命名变量对象(对于命名变量对象(简称),最后三位应该设置为000;),最后三位应该设置为000;
-- 对于vaa-name对象,最后三位必须设置为111。
当请求失败时,confiredserviceerror APDU仅与InitiaterRequest、ReadRequest和WriteRequest APDU一起使用,以提供诊断信息。
ConfirmedServiceError ::= CHOICE
{
-- tag 0 is reserved
-- In DLMS/COSEM only initiateEror, read and write are relevant
initiateError [1] ServiceError,
getStatus [2] ServiceError,
getNameList [3] ServiceError,
getVariableAttribute [4] ServiceError,
read [5] ServiceError,
write [6] ServiceError,
getDataSetAttribute [7] ServiceError,
getTIAttribute [8] ServiceError,
changeScope [9] ServiceError,
start [10] ServiceError,
stop [11] ServiceError,
resume [12] ServiceError,
makeUsable [13] ServiceError,
initiateLoad [14] ServiceError,
loadSegment [15] ServiceError,
terminateLoad [16] ServiceError,
initiateUpLoad [17] ServiceError,
upLoadSegment [18] ServiceError,
terminateUpLoad [19] ServiceError
}
ServiceError ::= CHOICE
{
application-reference [0] IMPLICIT ENUMERATED
{
-- DLMS provider only
other (0),
time-elapsed (1), -- time out since request sent
application-unreachable (2), -- peer AEi not reachable
application-reference-invalid (3), -- addressing trouble
application-context-unsupported (4), -- application-context incompatibility
provider-communication-error (5), -- error at the local or distant equipment
deciphering-error (6) -- error detected by the deciphering function
},
hardware-resource [1] IMPLICIT ENUMERATED
{
-- VDE hardware troubles
other (0),
memory-unavailable (1),
processor-resource-unavailable (2),
mass-storage-unavailable (3),
other-resource-unavailable (4)
},
vde-state-error [2] IMPLICIT ENUMERATED
{
-- Error source description
other (0),
no-dlms-context (1),
loading-data-set (2),
status-nochange (3),
status-inoperable (4)
},
service [3] IMPLICIT ENUMERATED
{
-- service handling troubles
other (0),
pdu-size (1), -- pdu too long
service-unsupported (2) -- as defined in the conformance block
},
definition [4] IMPLICIT ENUMERATED
{
-- object bound troubles in a service
other (0),
object-undefined (1), -- object not defined at the VDE
object-class-inconsistent (2), -- class of object incompatible with asked service
object-attribute-inconsistent (3) -- object attributes are inconsistent
},
access [5] IMPLICIT ENUMERATED
{
-- object access error
other (0),
scope-of-access-violated (1), -- access denied through authorisation reason
object-access-violated (2), -- access incompatible with object attribute
hardware-fault (3), -- access fail for hardware reason
object-unavailable (4) -- VDE hands object for unavailable
},
initiate [6] IMPLICIT ENUMERATED
{
-- initiate service error
other (0),
dlms-version-too-low (1), -- proposed DLMS version too low
incompatible-conformance (2), -- proposed service not sufficient
pdu-size-too-short (3), -- proposed PDU size too short
refused-by-the-VDE-Handler (4) -- vaa creation impossible or not allowed
},
load-data-set [7] IMPLICIT ENUMERATED
{
-- data set load services error
other (0),
primitive-out-of-sequence (1), -- according to the DataSet loading state transitions
not-loadable (2), -- loadable attribute set to FALSE
dataset-size-too-large (3), -- evaluated Data Set size too large
not-awaited-segment (4), -- proposed segment not awaited
interpretation-failure (5), -- segment interpretation error
storage-failure (6), -- segment storage error
data-set-not-ready (7) -- Data Set not in correct state for uploading
},
-- change-scope [8] IMPLICIT ENUMERATED
task [9] IMPLICIT ENUMERATED
{
-- TI services error
other (0),
no-remote-control (1), -- Remote Control parameter set to FALSE
ti-stopped (2), -- TI in stopped state
ti-running (3), -- TI in running state
ti-unusable (4) -- TI in unusable state
}
-- other [10] IMPLICIT ENUMERATED
}
-- COSEM APDUs using short name referencing
ReadRequest ::= SEQUENCE OF Variable-Access-Specification
ReadResponse ::= SEQUENCE OF CHOICE
{
data [0] Data,
data-access-error [1] IMPLICIT Data-Access-Result,
data-block-result [2] IMPLICIT Data-Block-Result,
block-number [3] IMPLICIT Unsigned16
}
WriteRequest ::= SEQUENCE
{
variable-access-specification SEQUENCE OF Variable-Access-Specification,
list-of-data SEQUENCE OF Data
}
WriteResponse ::= SEQUENCE OF CHOICE
{
success [0] IMPLICIT NULL,
data-access-error [1] IMPLICIT Data-Access-Result,
block-number [2] Unsigned16
}
UnconfirmedWriteRequest ::= SEQUENCE
{
variable-access-specification SEQUENCE OF Variable-Access-Specification,
list-of-data SEQUENCE OF Data
}
InformationReportRequest ::= SEQUENCE
{
current-time GeneralizedTime OPTIONAL,
variable-access-specification SEQUENCE OF Variable-Access-Specification,
list-of-data SEQUENCE OF Data
}
-- 使用LN referencing的COSEM apdu
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-Normal ::= SEQUENCE
{
invoke-id-and-priority Invoke-Id-And-Priority,
cosem-attribute-descriptor Cosem-Attribute-Descriptor,
access-selection Selective-Access-Descriptor OPTIONAL
}
Get-Request-Next ::= SEQUENCE
{
invoke-id-and-priority Invoke-Id-And-Priority,
block-number Unsigned32
}
Get-Request-With-List ::= SEQUENCE
{
invoke-id-and-priority Invoke-Id-And-Priority,
attribute-descriptor-list SEQUENCE OF Cosem-Attribute-Descriptor-With-Selection
}
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-Response-With-Datablock ::= SEQUENCE
{
invoke-id-and-priority Invoke-Id-And-Priority,
result DataBlock-G
}
Get-Response-With-List ::= SEQUENCE
{
invoke-id-and-priority Invoke-Id-And-Priority,
result SEQUENCE OF Get-Data-Result
}
Set-Request ::= CHOICE
{
set-request-normal [1] IMPLICIT Set-Request-Normal,
set-request-with-first-datablock [2] IMPLICIT Set-Request-With-First-Datablock,
set-request-with-datablock [3] IMPLICIT Set-Request-With-Datablock,
set-request-with-list [4] IMPLICIT Set-Request-With-List,
set-request-with-list-and-first-datablock [5] IMPLICIT Set-Request-With-List-And-First-Datablock
}
Set-Request-Normal ::= SEQUENCE
{
invoke-id-and-priority Invoke-Id-And-Priority,
cosem-attribute-descriptor Cosem-Attribute-Descriptor,
access-selection Selective-Access-Descriptor OPTIONAL,
value Data
}
Set-Request-With-First-Datablock ::= SEQUENCE
{
invoke-id-and-priority Invoke-Id-And-Priority,
cosem-attribute-descriptor Cosem-Attribute-Descriptor,
access-selection [0] IMPLICIT Selective-Access-Descriptor OPTIONAL,
datablock DataBlock-SA
}
Set-Request-With-Datablock ::= SEQUENCE
{
invoke-id-and-priority Invoke-Id-And-Priority,
datablock DataBlock-SA
}
Set-Request-With-List ::= SEQUENCE
{
invoke-id-and-priority Invoke-Id-And-Priority,
attribute-descriptor-list SEQUENCE OF Cosem-Attribute-Descriptor-With-Selection,
value-list SEQUENCE OF Data
}
Set-Request-With-List-And-First-Datablock ::= SEQUENCE
{
invoke-id-and-priority Invoke-Id-And-Priority,
attribute-descriptor-list SEQUENCE OF Cosem-Attribute-Descriptor-With-Selection,
datablock DataBlock-SA
}
Set-Response ::= CHOICE
{
set-response-normal [1] IMPLICIT Set-Response-Normal,
set-response-datablock [2] IMPLICIT Set-Response-Datablock,
set-response-last-datablock [3] IMPLICIT Set-Response-Last-Datablock,
set-response-last-datablock-with-list [4] IMPLICIT Set-Response-Last-Datablock-With-List,
set-response-with-list [5] IMPLICIT Set-Response-With-List
}
Set-Response-Normal ::= SEQUENCE
{
invoke-id-and-priority Invoke-Id-And-Priority,
result Data-Access-Result
}
Set-Response-Datablock ::= SEQUENCE
{
invoke-id-and-priority Invoke-Id-And-Priority,
block-number Unsigned32
}
Set-Response-Last-Datablock ::= SEQUENCE
{
invoke-id-and-priority Invoke-Id-And-Priority,
result Data-Access-Result,
block-number Unsigned32
}
Set-Response-Last-Datablock-With-List ::= SEQUENCE
{
invoke-id-and-priority Invoke-Id-And-Priority,
result SEQUENCE OF Data-Access-Result,
block-number Unsigned32
}
Set-Response-With-List ::= SEQUENCE
{
invoke-id-and-priority Invoke-Id-And-Priority,
result SEQUENCE OF Data-Access-Result
}
Action-Request ::= CHOICE
{
action-request-normal [1] IMPLICIT Action-Request-Normal,
action-request-next-pblock [2] IMPLICIT Action-Request-Next-Pblock,
action-request-with-list [3] IMPLICIT Action-Request-With-List,
action-request-with-first-pblock [4] IMPLICIT Action-Request-With-First-Pblock,
action-request-with-list-and-first-pblock [5] IMPLICIT Action-Request-With-List-And-First-Pblock,
action-request-with-pblock [6] IMPLICIT Action-Request-With-Pblock
}
Action-Request-Normal ::= SEQUENCE
{
invoke-id-and-priority Invoke-Id-And-Priority,
cosem-method-descriptor Cosem-Method-Descriptor,
method-invocation-parameters Data OPTIONAL
}
Action-Request-Next-Pblock ::= SEQUENCE
{
invoke-id-and-priority Invoke-Id-And-Priority,
block-number Unsigned32
}
Action-Request-With-List ::= SEQUENCE
{
invoke-id-and-priority Invoke-Id-And-Priority,
cosem-method-descriptor-list SEQUENCE OF Cosem-Method-Descriptor,
method-invocation-parameters SEQUENCE OF Data
}
Action-Request-With-First-Pblock ::= SEQUENCE
{
invoke-id-and-priority Invoke-Id-And-Priority,
cosem-method-descriptor Cosem-Method-Descriptor,
pblock DataBlock-SA
}
Action-Request-With-List-And-First-Pblock ::= SEQUENCE
{
invoke-id-and-priority Invoke-Id-And-Priority,
cosem-method-descriptor-list SEQUENCE OF Cosem-Method-Descriptor,
pblock DataBlock-SA
}
Action-Request-With-Pblock ::= SEQUENCE
{
invoke-id-and-priority Invoke-Id-And-Priority,
pblock DataBlock-SA
}
Action-Response ::= CHOICE
{
action-response-normal [1] IMPLICIT Action-Response-Normal,
action-response-with-pblock [2] IMPLICIT Action-Response-With-Pblock,
action-response-with-list [3] IMPLICIT Action-Response-With-List,
action-response-next-pblock [4] IMPLICIT Action-Response-Next-Pblock
}
Action-Response-Normal ::= SEQUENCE
{
invoke-id-and-priority Invoke-Id-And-Priority,
single-response Action-Response-With-Optional-Data
}
Action-Response-With-Pblock ::= SEQUENCE
{
invoke-id-and-priority Invoke-Id-And-Priority,
pblock DataBlock-SA
}
Action-Response-With-List ::= SEQUENCE
{
invoke-id-and-priority Invoke-Id-And-Priority,
list-of-responses SEQUENCE OF Action-Response-With-Optional-Data
}
Action-Response-Next-Pblock ::= SEQUENCE
{
invoke-id-and-priority Invoke-Id-And-Priority,
block-number Unsigned32
}
EventNotificationRequest ::= SEQUENCE
{
time OCTET STRING OPTIONAL,
cosem-attribute-descriptor Cosem-Attribute-Descriptor,
attribute-value Data
}
ExceptionResponse ::= SEQUENCE
{
state-error [0] IMPLICIT ENUMERATED
{
service-not-allowed (1),
service-unknown (2)
},
service-error [1] CHOICE
{
operation-not-possible [1] IMPLICIT NULL,
service-not-supported [2] IMPLICIT NULL,
other-reason [3] IMPLICIT NULL,
pdu-too-long [4] IMPLICIT NULL,
deciphering-error [5] IMPLICIT NULL,
invocation-counter-error [6] IMPLICIT Unsigned32
}
}
-- Access
Access-Request ::= SEQUENCE
{
long-invoke-id-and-priority Long-Invoke-Id-And-Priority,
date-time OCTET STRING,
access-request-body Access-Request-Body
}
Access-Response ::= SEQUENCE
{
long-invoke-id-and-priority Long-Invoke-Id-And-Priority,
date-time OCTET STRING,
access-response-body Access-Response-Body
}
-- Data-Notification
Data-Notification ::= SEQUENCE
{
long-invoke-id-and-priority Long-Invoke-Id-And-Priority,
date-time OCTET STRING,
notification-body Notification-Body
}
-- General APDUs
General-Ded-Ciphering ::= SEQUENCE
{
system-title OCTET STRING,
ciphered-content OCTET STRING
}
General-Glo-Ciphering ::= SEQUENCE
{
system-title OCTET STRING,
ciphered-content OCTET STRING
}
General-Ciphering ::= SEQUENCE
{
transaction-id OCTET STRING,
originator-system-title OCTET STRING,
recipient-system-title OCTET STRING,
date-time OCTET STRING,
other-information OCTET STRING,
key-info Key-Info OPTIONAL,
ciphered-content OCTET STRING
}
General-Signing ::= SEQUENCE
{
transaction-id OCTET STRING,
originator-system-title OCTET STRING,
recipient-system-title OCTET STRING,
date-time OCTET STRING,
other-information OCTET STRING,
content OCTET STRING,
signature OCTET STRING
}
General-Block-Transfer ::= SEQUENCE
{
block-control Block-Control,
block-number Unsigned16,
block-number-ack Unsigned16,
block-data OCTET STRING
}
-- Types used in the xDLMS data transfer services
Variable-Access-Specification ::= CHOICE
{
variable-name [2] IMPLICIT ObjectName,
-- detailed-access [3] is not used in DLMS/COSEM
parameterized-access [4] IMPLICIT Parameterized-Access,
block-number-access [5] IMPLICIT Block-Number-Access,
read-data-block-access [6] IMPLICIT Read-Data-Block-Access,
write-data-block-access [7] IMPLICIT Write-Data-Block-Access
}
Parameterized-Access ::= SEQUENCE
{
variable-name ObjectName,
selector Unsigned8,
parameter Data
}
Block-Number-Access ::= SEQUENCE
{
block-number Unsigned16
}
Read-Data-Block-Access ::= SEQUENCE
{
last-block BOOLEAN,
block-number Unsigned16,
raw-data OCTET STRING
}
Write-Data-Block-Access ::= SEQUENCE
{
last-block BOOLEAN,
block-number Unsigned16
}
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,
octet-string [9] IMPLICIT OCTET STRING,
visible-string [10] IMPLICIT VisibleString,
utf8-string [12] IMPLICIT UTF8String,
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 Unsigned8,
float32 [23] IMPLICIT OCTET STRING (SIZE(4)),
float64 [24] IMPLICIT OCTET STRING (SIZE(8)),
date-time [25] IMPLICIT OCTET STRING (SIZE(12)),
date [26] IMPLICIT OCTET STRING (SIZE(5)),
time [27] IMPLICIT OCTET STRING (SIZE(4)),
dont-care [255] IMPLICIT NULL
}
-- The following TypeDescription relates to the compact-array data Type
TypeDescription ::= CHOICE
{
null-data [0] IMPLICIT NULL,
array [1] IMPLICIT SEQUENCE
{
number-of-elements Unsigned16,
type-description TypeDescription
},
structure [2] IMPLICIT SEQUENCE OF TypeDescription,
boolean [3] IMPLICIT NULL,
bit-string [4] IMPLICIT NULL,
double-long [5] IMPLICIT NULL,
double-long-unsigned [6] IMPLICIT NULL,
octet-string [9] IMPLICIT NULL,
visible-string [10] IMPLICIT NULL,
utf8-string [12] IMPLICIT NULL,
bcd [13] IMPLICIT NULL,
integer [15] IMPLICIT NULL,
long [16] IMPLICIT NULL,
unsigned [17] IMPLICIT NULL,
long-unsigned [18] IMPLICIT NULL,
long64 [20] IMPLICIT NULL,
long64-unsigned [21] IMPLICIT NULL,
enum [22] IMPLICIT NULL,
float32 [23] IMPLICIT NULL,
float64 [24] IMPLICIT NULL,
date-time [25] IMPLICIT NULL,
date [26] IMPLICIT NULL,
time [27] IMPLICIT NULL,
dont-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),
data-block-number-invalid (19),
other-reason (250)
}
Action-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-action-aborted (15),
no-long-action-in-progress (16),
other-reason (250)
}
-- IEC 61334-6第5条规定,任何字节的位从1到8编号,其中第8位是最重要的。在DLMS UA绿皮书中,位的编号从0到7。调用id和优先级的使用
-- invoke-id bits 0-3
-- reserved bits 4-5
-- service-class bit 6 0 = Unconfirmed, 1 = Confirmed
-- priority bit 7 0 = Normal, 1 = High
Invoke-Id-And-Priority ::= Unsigned8
-- Use of Long-Invoke-Id-And-Priority
-- long-invoke-id bits 0-23
-- reserved bits 24-27
-- self-descriptive bit 28 0 = Not-Self-Descriptive, 1 = Self-Descriptive
-- processing-option bit 29 0 = Continue on Error, 1 = Break on Error
-- service-class bit 30 0 = Unconfirmed, 1 = Confirmed
-- priority bit 31 0 = Normal, 1 = High
Long-Invoke-Id-And-Priority ::= Unsigned32
Cosem-Attribute-Descriptor ::= SEQUENCE
{
class-id Cosem-Class-Id,
instance-id Cosem-Object-Instance-Id,
attribute-id Cosem-Object-Attribute-Id
}
Cosem-Method-Descriptor ::= SEQUENCE
{
class-id Cosem-Class-Id,
instance-id Cosem-Object-Instance-Id,
method-id Cosem-Object-Method-Id
}
Cosem-Class-Id ::= Unsigned16
Cosem-Object-Instance-Id ::= OCTET STRING (SIZE(6))
Cosem-Object-Attribute-Id ::= Integer8
Cosem-Object-Method-Id ::= Integer8
Selective-Access-Descriptor ::= SEQUENCE
{
access-selector Unsigned8,
access-parameters Data
}
Cosem-Attribute-Descriptor-With-Selection ::= SEQUENCE
{
cosem-attribute-descriptor Cosem-Attribute-Descriptor,
access-selection Selective-Access-Descriptor OPTIONAL
}
Get-Data-Result ::= CHOICE
{
data [0] Data,
data-access-result [1] IMPLICIT Data-Access-Result
}
Data-Block-Result ::= SEQUENCE -- Used in ReadResponse with block transfer
{
last-block BOOLEAN,
block-number Unsigned16,
raw-data OCTET STRING
}
DataBlock-G ::= SEQUENCE -- G == DataBlock for the GET-response
{
last-block BOOLEAN,
block-number Unsigned32,
result CHOICE
{
raw-data [0] IMPLICIT OCTET STRING,
data-access-result [1] IMPLICIT Data-Access-Result
}
}
DataBlock-SA ::= SEQUENCE -- SA == SET请求、ACTION请求和ACTION响应的DataBlock
{
last-block BOOLEAN,
block-number Unsigned32,
raw-data OCTET STRING
}
Action-Response-With-Optional-Data ::= SEQUENCE
{
result Action-Result,
return-parameters Get-Data-Result OPTIONAL
}
Notification-Body ::= SEQUENCE
{
data-value Data
}
List-Of-Data ::= SEQUENCE OF Data
Access-Request-Get ::= SEQUENCE
{
cosem-attribute-descriptor Cosem-Attribute-Descriptor
}
Access-Request-Get-With-Selection ::= SEQUENCE
{
cosem-attribute-descriptor Cosem-Attribute-Descriptor,
access-selection Selective-Access-Descriptor
}
Access-Request-Set ::= SEQUENCE
{
cosem-attribute-descriptor Cosem-Attribute-Descriptor
}
Access-Request-Set-With-Selection ::= SEQUENCE
{
cosem-attribute-descriptor Cosem-Attribute-Descriptor,
access-selection Selective-Access-Descriptor
}
Access-Request-Action ::= SEQUENCE
{
cosem-method-descriptor Cosem-Method-Descriptor
}
Access-Request-Specification ::= CHOICE
{
access-request-get [1] Access-Request-Get,
access-request-set [2] Access-Request-Set,
access-request-action [3] Access-Request-Action,
access-request-get-with-selection [4] Access-Request-Get-With-Selection,
access-request-set-with-selection [5] Access-Request-Set-With-Selection
}
List-Of-Access-Request-Specification ::= SEQUENCE OF Access-Request-Specification
Access-Request-Body ::= SEQUENCE
{
access-request-specification List-Of-Access-Request-Specification,
access-request-list-of-data List-Of-Data
}
Access-Response-Get ::= SEQUENCE
{
result Data-Access-Result
}
Access-Response-Set ::= SEQUENCE
{
result Data-Access-Result
}
Access-Response-Action ::= SEQUENCE
{
result Action-Result
}
Access-Response-Specification ::= CHOICE
{
access-response-get [1] Access-Response-Get,
access-response-set [2] Access-Response-Set,
access-response-action [3] Access-Response-Action
}
List-Of-Access-Response-Specification ::= SEQUENCE OF Access-Response-Specification
Access-Response-Body ::= SEQUENCE
{
access-request-specification [0] List-Of-Access-Request-Specification OPTIONAL,
access-response-list-of-data List-Of-Data,
access-response-specification List-Of-Access-Response-Specification
}
-- Key-info
Key-Id ::= ENUMERATED
{
global-unicast-encryption-key (0),
global-broadcast-encryption-key (1)
}
Kek-Id ::= ENUMERATED
{
master-key (0)
}
Identified-Key ::= SEQUENCE
{
key-id Key-Id
}
Wrapped-Key ::= SEQUENCE
{
kek-id Kek-Id,
key-ciphered-data OCTET STRING
}
Agreed-Key ::= SEQUENCE
{
key-parameters OCTET STRING,
key-ciphered-data OCTET STRING
}
Key-Info ::= CHOICE
{
identified-key [0] Identified-Key,
wrapped-key [1] Wrapped-Key,
agreed-key [2] Agreed-Key
}
-- Use of Block-Control
-- window bits 0-5 window advertise
-- streaming bit 6 0 = No Streaming active, 1 = Streaming active
-- last-block bit 7 0 = Not Last Block, 1 = Last Block
Block-Control ::= Unsigned8
END
s9.6 COSEM PDU XML schema
9.6.1 General
ITU-T的X.693和X.694建议书提供了针对ASN.1的XML编码规则和针对ASN.1的XML模式定义语言(XSD)映射。没有提供将ASN.1映射到XSD的建议。
XML在IT行业中得到了广泛的接受。这种编码的目的是使COSEM模型内容能够以各种方式以XML编码内容的形式进行传输。它可以是应用程序之间交换的XML文档、包含在Web服务SOAP消息中的内容或封装在电子邮件消息中的内容,仅举几个应用程序的例子。
ASN.1编码apdu和XML编码内容之间的互操作性和映射在两个方向上都很重要。一方面,ASN.1支持创建支持XML编码规则的XML编码内容(参见ITU-T X.693和ITU-T X.694)。另一方面,IT行业正在寻找使用XML优化封装的最佳XML内容传输的解决方案。为此,在W3C XML Schema和ASN.1定义之间进行转换至关重要。
双向转换支持将XML内容正确地转换为ASN.1编码的内容,反之亦然。子条款9.6.2包含了COSEMPdu ASN.1定义到COSEMPdu XML Schema (XSD)的映射。
9.6.2 XML Schema
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.dlms.com/COSEMpdu" targetNamespace="http://www.dlms.com/COSEMpdu" elementFormDefault="qualified">
<!-- ASN.1 definitions -->
<xsd:complexType name="NULL" final="#all"/>
<xsd:simpleType name="BitString">
<xsd:restriction base="xsd:string">
<xsd:pattern value="[0-1]{0,}"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ObjectIdentifier">
<xsd:restriction base="xsd:token">
<xsd:pattern value="[0-2](\.[1-3]?[0-9]?(\.\d+)`)?"/>
</xsd:restriction>
</xsd:simpleType>
<!-- ACSE-APDU definition -->
<xsd:element name="aCSE-APDU" type="ACSE-APDU"/>
<xsd:complexType name="ACSE-APDU">
<xsd:choice>
<xsd:element name="aarq" type="AARQ-apdu"/>
<xsd:element name="aare" type="AARE-apdu"/>
<xsd:element name="rlrq" type="RLRQ-apdu"/>
<xsd:element name="rlre" type="RLRE-apdu"/>
</xsd:choice>
</xsd:complexType>
<!-- xDLMS-APDU definition -->
<xsd:element name="xDLMS-APDU" type="XDLMS-APDU"/>
<xsd:complexType name="XDLMS-APDU">
<xsd:choice>
<xsd:element name="initiateRequest" type="InitiateRequest"/>
<xsd:element name="readRequest" type="ReadRequest"/>
<xsd:element name="writeRequest" type="WriteRequest"/>
<xsd:element name="initiateResponse" type="InitiateResponse"/>
<xsd:element name="readResponse" type="ReadResponse"/>
<xsd:element name="writeResponse" type="WriteResponse"/>
<xsd:element name="confirmedServiceError" type="ConfirmedServiceError"/>
<xsd:element name="data-notification" type="Data-Notification"/>
<xsd:element name="unconfirmedWriteRequest" type="UnconfirmedWriteRequest"/>
<xsd:element name="informationReportRequest" type="InformationReportRequest"/>
<xsd:element name="glo-initiateRequest" type="xsd:hexBinary"/>
<xsd:element name="glo-readRequest" type="xsd:hexBinary"/>
<xsd:element name="glo-writeRequest" type="xsd:hexBinary"/>
<xsd:element name="glo-initiateResponse" type="xsd:hexBinary"/>
<xsd:element name="glo-readResponse" type="xsd:hexBinary"/>
<xsd:element name="glo-writeResponse" type="xsd:hexBinary"/>
<xsd:element name="glo-confirmedServiceError" type="xsd:hexBinary"/>
<xsd:element name="glo-unconfirmedWriteRequest" type="xsd:hexBinary"/>
<xsd:element name="glo-informationReportRequest" type="xsd:hexBinary"/>
<xsd:element name="ded-initiateRequest" type="xsd:hexBinary"/>
<xsd:element name="ded-readRequest" type="xsd:hexBinary"/>
<xsd:element name="ded-writeRequest" type="xsd:hexBinary"/>
<xsd:element name="ded-initiateResponse" type="xsd:hexBinary"/>
<xsd:element name="ded-readResponse" type="xsd:hexBinary"/>
<xsd:element name="ded-writeResponse" type="xsd:hexBinary"/>
<xsd:element name="ded-confirmedServiceError" type="xsd:hexBinary"/>
<xsd:element name="ded-unconfirmedWriteRequest" type="xsd:hexBinary"/>
<xsd:element name="ded-informationReportRequest" type="xsd:hexBinary"/>
<xsd:element name="get-request" type="Get-Request"/>
<xsd:element name="set-request" type="Set-Request"/>
<xsd:element name="event-notification-request" type="EventNotificationRequest"/>
<xsd:element name="action-request" type="Action-Request"/>
<xsd:element name="get-response" type="Get-Response"/>
<xsd:element name="set-response" type="Set-Response"/>
<xsd:element name="action-response" type="Action-Response"/>
<xsd:element name="glo-get-request" type="xsd:hexBinary"/>
<xsd:element name="glo-set-request" type="xsd:hexBinary"/>
<xsd:element name="glo-event-notification-request" type="xsd:hexBinary"/>
<xsd:element name="glo-action-request" type="xsd:hexBinary"/>
<xsd:element name="glo-get-response" type="xsd:hexBinary"/>
<xsd:element name="glo-set-response" type="xsd:hexBinary"/>
<xsd:element name="glo-action-response" type="xsd:hexBinary"/>
<xsd:element name="ded-get-request" type="xsd:hexBinary"/>
<xsd:element name="ded-set-request" type="xsd:hexBinary"/>
<xsd:element name="ded-event-notification-request" type="xsd:hexBinary"/>
<xsd:element name="ded-actionRequest" type="xsd:hexBinary"/>
<xsd:element name="ded-get-response" type="xsd:hexBinary"/>
<xsd:element name="ded-set-response" type="xsd:hexBinary"/>
<xsd:element name="ded-action-response" type="xsd:hexBinary"/>
<xsd:element name="exception-response" type="ExceptionResponse"/>
<xsd:element name="access-request" type="Access-Request"/>
<xsd:element name="access-response" type="Access-Response"/>
<xsd:element name="general-glo-ciphering" type="General-Glo-Ciphering"/>
<xsd:element name="general-ded-ciphering" type="General-Ded-Ciphering"/>
<xsd:element name="general-ciphering" type="General-Ciphering"/>
<xsd:element name="general-signing" type="General-Signing"/>
<xsd:element name="general-block-transfer" type="General-Block-Transfer"/>
</xsd:choice>
</xsd:complexType>
<xsd:simpleType name="Application-context-name">
<xsd:restriction base="ObjectIdentifier"/>
</xsd:simpleType>
<xsd:simpleType name="AP-title">
<xsd:restriction base="xsd:hexBinary"/>
</xsd:simpleType>
<xsd:simpleType name="AE-qualifier">
<xsd:restriction base="xsd:hexBinary"/>
</xsd:simpleType>
<xsd:simpleType name="AP-invocation-identifier">
<xsd:restriction base="xsd:integer"/>
</xsd:simpleType>
<xsd:simpleType name="AE-invocation-identifier">
<xsd:restriction base="xsd:integer"/>
</xsd:simpleType>
<xsd:simpleType name="ACSE-requirements">
<xsd:union memberTypes="BitString">
<xsd:simpleType>
<xsd:list>
<xsd:simpleType>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="authentication"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:list>
</xsd:simpleType>
</xsd:union>
</xsd:simpleType>
<xsd:simpleType name="Mechanism-name">
<xsd:restriction base="ObjectIdentifier"/>
</xsd:simpleType>
<xsd:simpleType name="Implementation-data">
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="Association-information">
<xsd:restriction base="xsd:hexBinary"/>
</xsd:simpleType>
<xsd:simpleType name="Association-result">
<xsd:union>
<xsd:simpleType>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="accepted"/>
<xsd:enumeration value="rejected-permanent"/>
<xsd:enumeration value="rejected-transient"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType>
<xsd:restriction base="xsd:integer"/>
</xsd:simpleType>
</xsd:union>
</xsd:simpleType>
<xsd:simpleType name="Release-request-reason">
<xsd:union>
<xsd:simpleType>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="normal"/>
<xsd:enumeration value="urgent"/>
<xsd:enumeration value="user-defined"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType>
<xsd:restriction base="xsd:integer"/>
</xsd:simpleType>
</xsd:union>
</xsd:simpleType>
<xsd:simpleType name="Release-response-reason">
<xsd:union>
<xsd:simpleType>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="normal"/>
<xsd:enumeration value="not-finished"/>
<xsd:enumeration value="user-defined"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType>
<xsd:restriction base="xsd:integer"/>
</xsd:simpleType>
</xsd:union>
</xsd:simpleType>
<xsd:simpleType name="Integer8">
<xsd:restriction base="xsd:byte"/>
</xsd:simpleType>
<xsd:simpleType name="Integer16">
<xsd:restriction base="xsd:short"/>
</xsd:simpleType>
<xsd:simpleType name="Integer32">
<xsd:restriction base="xsd:int"/>
</xsd:simpleType>
<xsd:simpleType name="Integer64">
<xsd:restriction base="xsd:long"/>
</xsd:simpleType>
<xsd:simpleType name="Unsigned8">
<xsd:restriction base="xsd:unsignedByte"/>
</xsd:simpleType>
<xsd:simpleType name="Unsigned16">
<xsd:restriction base="xsd:unsignedShort"/>
</xsd:simpleType>
<xsd:simpleType name="Unsigned32">
<xsd:restriction base="xsd:unsignedInt"/>
</xsd:simpleType>
<xsd:simpleType name="Unsigned64">
<xsd:restriction base="xsd:unsignedLong"/>
</xsd:simpleType>
<xsd:simpleType name="Conformance">
<xsd:union memberTypes="BitString">
<xsd:simpleType>
<xsd:list>
<xsd:simpleType>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="reserved-zero"/>
<xsd:enumeration value="general-protection"/>
<xsd:enumeration value="general-block-transfer"/>
<xsd:enumeration value="read"/>
<xsd:enumeration value="write"/>
<xsd:enumeration value="unconfirmed-write"/>
<xsd:enumeration value="reserved-six"/>
<xsd:enumeration value="reserved-seven"/>
<xsd:enumeration value="attribute0-supported-with-set"/>
<xsd:enumeration value="priority-mgmt-supported"/>
<xsd:enumeration value="attribute0-supported-with-get"/>
<xsd:enumeration value="block-transfer-with-get-or-read"/>
<xsd:enumeration value="block-transfer-with-set-or-write"/>
<xsd:enumeration value="block-transfer-with-action"/>
<xsd:enumeration value="multiple-references"/>
<xsd:enumeration value="information-report"/>
<xsd:enumeration value="data-notification"/>
<xsd:enumeration value="access"/>
<xsd:enumeration value="parameterized-access"/>
<xsd:enumeration value="get"/>
<xsd:enumeration value="set"/>
<xsd:enumeration value="selective-access"/>
<xsd:enumeration value="event-notification"/>
<xsd:enumeration value="action"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:list>
</xsd:simpleType>
</xsd:union>
</xsd:simpleType>
<xsd:simpleType name="ObjectName">
<xsd:restriction base="Integer16"/>
</xsd:simpleType>
<xsd:simpleType name="Data-Access-Result">
<xsd:restriction base="xsd:token">
<xsd:enumeration value="success"/>
<xsd:enumeration value="hardware-fault"/>
<xsd:enumeration value="temporary-failure"/>
<xsd:enumeration value="read-write-denied"/>
<xsd:enumeration value="object-undefined"/>
<xsd:enumeration value="object-class-inconsistent"/>
<xsd:enumeration value="object-unavailable"/>
<xsd:enumeration value="type-unmatched"/>
<xsd:enumeration value="scope-of-access-violated"/>
<xsd:enumeration value="data-block-unavailable"/>
<xsd:enumeration value="long-get-aborted"/>
<xsd:enumeration value="no-long-get-in-progress"/>
<xsd:enumeration value="long-set-aborted"/>
<xsd:enumeration value="no-long-set-in-progress"/>
<xsd:enumeration value="data-block-number-invalid"/>
<xsd:enumeration value="other-reason"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="Action-Result">
<xsd:restriction base="xsd:token">
<xsd:enumeration value="success"/>
<xsd:enumeration value="hardware-fault"/>
<xsd:enumeration value="temporary-failure"/>
<xsd:enumeration value="read-write-denied"/>
<xsd:enumeration value="object-undefined"/>
<xsd:enumeration value="object-class-inconsistent"/>
<xsd:enumeration value="object-unavailable"/>
<xsd:enumeration value="type-unmatched"/>
<xsd:enumeration value="scope-of-access-violated"/>
<xsd:enumeration value="data-block-unavailable"/>
<xsd:enumeration value="long-action-aborted"/>
<xsd:enumeration value="no-long-action-in-progress"/>
<xsd:enumeration value="other-reason"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="Invoke-Id-And-Priority">
<xsd:restriction base="Unsigned8"/>
</xsd:simpleType>
<xsd:simpleType name="Long-Invoke-Id-And-Priority">
<xsd:restriction base="Unsigned32"/>
</xsd:simpleType>
<xsd:simpleType name="Cosem-Class-Id">
<xsd:restriction base="Unsigned16"/>
</xsd:simpleType>
<xsd:simpleType name="Cosem-Object-Instance-Id">
<xsd:restriction base="xsd:hexBinary">
<xsd:length value="6"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="Cosem-Object-Attribute-Id">
<xsd:restriction base="Integer8"/>
</xsd:simpleType>
<xsd:simpleType name="Cosem-Object-Method-Id">
<xsd:restriction base="Integer8"/>
</xsd:simpleType>
<xsd:simpleType name="Key-Id">
<xsd:restriction base="xsd:token">
<xsd:enumeration value="global-unicast-encryption-key"/>
<xsd:enumeration value="global-broadcast-encryption-key"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="Kek-Id">
<xsd:restriction base="xsd:token">
<xsd:enumeration value="master-key"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="Block-Control">
<xsd:restriction base="Unsigned8"/>
</xsd:simpleType>
<xsd:complexType name="Authentication-value">
<xsd:choice>
<xsd:element name="charstring" type="xsd:string"/>
<xsd:element name="bitstring" type="BitString"/>
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="AARQ-apdu">
<xsd:sequence>
<xsd:element name="protocol-version" minOccurs="0">
<xsd:simpleType>
<xsd:union memberTypes="BitString">
<xsd:simpleType>
<xsd:list>
<xsd:simpleType>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="version1"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:list>
</xsd:simpleType>
</xsd:union>
</xsd:simpleType>
</xsd:element>
<xsd:element name="application-context-name" type="Application-context-name"/>
<xsd:element name="called-AP-title" minOccurs="0" type="AP-title"/>
<xsd:element name="called-AE-qualifier" minOccurs="0" type="AE-qualifier"/>
<xsd:element name="called-AP-invocation-id" minOccurs="0" type="AP-invocation-identifier"/>
<xsd:element name="called-AE-invocation-id" minOccurs="0" type="AE-invocation-identifier"/>
<xsd:element name="calling-AP-title" minOccurs="0" type="AP-title"/>
<xsd:element name="calling-AE-qualifier" minOccurs="0" type="AE-qualifier"/>
<xsd:element name="calling-AP-invocation-id" minOccurs="0" type="AP-invocation-identifier"/>
<xsd:element name="calling-AE-invocation-id" minOccurs="0" type="AE-invocation-identifier"/>
<xsd:element name="sender-acse-requirements" minOccurs="0" type="ACSE-requirements"/>
<xsd:element name="mechanism-name" minOccurs="0" type="Mechanism-name"/>
<xsd:element name="calling-authentication-value" minOccurs="0" type="Authentication-value"/>
<xsd:element name="implementation-information" minOccurs="0" type="Implementation-data"/>
<xsd:element name="user-information" minOccurs="0" type="Association-information"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Associate-source-diagnostic">
<xsd:choice>
<xsd:element name="acse-service-user">
<xsd:simpleType>
<xsd:union>
<xsd:simpleType>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="null"/>
<xsd:enumeration value="no-reason-given"/>
<xsd:enumeration value="application-context-name-not-supported"/>
<xsd:enumeration value="calling-AP-title-not-recognized"/>
<xsd:enumeration value="calling-AP-invocation-identifier-not-recognized"/>
<xsd:enumeration value="calling-AE-qualifier-not-recognized"/>
<xsd:enumeration value="calling-AE-invocation-identifier-not-recognized"/>
<xsd:enumeration value="called-AP-title-not-recognized"/>
<xsd:enumeration value="called-AP-invocation-identifier-not-recognized"/>
<xsd:enumeration value="called-AE-qualifier-not-recognized"/>
<xsd:enumeration value="called-AE-invocation-identifier-not-recognized"/>
<xsd:enumeration value="authentication-mechanism-name-not-recognised"/>
<xsd:enumeration value="authentication-mechanism-name-required"/>
<xsd:enumeration value="authentication-failure"/>
<xsd:enumeration value="authentication-required"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType>
<xsd:restriction base="xsd:integer"/>
</xsd:simpleType>
</xsd:union>
</xsd:simpleType>
</xsd:element>
<xsd:element name="acse-service-provider">
<xsd:simpleType>
<xsd:union>
<xsd:simpleType>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="null"/>
<xsd:enumeration value="no-reason-given"/>
<xsd:enumeration value="no-common-acse-version"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType>
<xsd:restriction base="xsd:integer"/>
</xsd:simpleType>
</xsd:union>
</xsd:simpleType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="AARE-apdu">
<xsd:sequence>
<xsd:element name="protocol-version" minOccurs="0">
<xsd:simpleType>
<xsd:union memberTypes="BitString">
<xsd:simpleType>
<xsd:list>
<xsd:simpleType>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="version1"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:list>
</xsd:simpleType>
</xsd:union>
</xsd:simpleType>
</xsd:element>
<xsd:element name="application-context-name" type="Application-context-name"/>
<xsd:element name="result" type="Association-result"/>
<xsd:element name="result-source-diagnostic" type="Associate-source-diagnostic"/>
<xsd:element name="responding-AP-title" minOccurs="0" type="AP-title"/>
<xsd:element name="responding-AE-qualifier" minOccurs="0" type="AE-qualifier"/>
<xsd:element name="responding-AP-invocation-id" minOccurs="0" type="AP-invocation-identifier"/>
<xsd:element name="responding-AE-invocation-id" minOccurs="0" type="AE-invocation-identifier"/>
<xsd:element name="responder-acse-requirements" minOccurs="0" type="ACSE-requirements"/>
<xsd:element name="mechanism-name" minOccurs="0" type="Mechanism-name"/>
<xsd:element name="responding-authentication-value" minOccurs="0" type="Authentication-value"/>
<xsd:element name="implementation-information" minOccurs="0" type="Implementation-data"/>
<xsd:element name="user-information" minOccurs="0" type="Association-information"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="RLRQ-apdu">
<xsd:sequence>
<xsd:element name="reason" minOccurs="0" type="Release-request-reason"/>
<xsd:element name="user-information" minOccurs="0" type="Association-information"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="RLRE-apdu">
<xsd:sequence>
<xsd:element name="reason" minOccurs="0" type="Release-response-reason"/>
<xsd:element name="user-information" minOccurs="0" type="Association-information"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="InitiateRequest">
<xsd:sequence>
<xsd:element name="dedicated-key" minOccurs="0" type="xsd:hexBinary"/>
<xsd:element name="response-allowed" default="true" type="xsd:boolean"/>
<xsd:element name="proposed-quality-of-service" minOccurs="0" type="Integer8"/>
<xsd:element name="proposed-dlms-version-number" type="Unsigned8"/>
<xsd:element name="proposed-conformance" type="Conformance"/>
<xsd:element name="client-max-receive-pdu-size" type="Unsigned16"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="TypeDescription">
<xsd:choice>
<xsd:element name="null-data" type="NULL"/>
<xsd:element name="array">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="number-of-elements" type="Unsigned16"/>
<xsd:element name="type-description" type="TypeDescription"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="structure">
<xsd:complexType>
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="TypeDescription" type="TypeDescription"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="boolean" type="NULL"/>
<xsd:element name="bit-string" type="NULL"/>
<xsd:element name="double-long" type="NULL"/>
<xsd:element name="double-long-unsigned" type="NULL"/>
<xsd:element name="octet-string" type="NULL"/>
<xsd:element name="visible-string" type="NULL"/>
<xsd:element name="utf8-string" type="NULL"/>
<xsd:element name="bcd" type="NULL"/>
<xsd:element name="integer" type="NULL"/>
<xsd:element name="long" type="NULL"/>
<xsd:element name="unsigned" type="NULL"/>
<xsd:element name="long-unsigned" type="NULL"/>
<xsd:element name="long64" type="NULL"/>
<xsd:element name="long64-unsigned" type="NULL"/>
<xsd:element name="enum" type="NULL"/>
<xsd:element name="float32" type="NULL"/>
<xsd:element name="float64" type="NULL"/>
<xsd:element name="date-time" type="NULL"/>
<xsd:element name="date" type="NULL"/>
<xsd:element name="time" type="NULL"/>
<xsd:element name="dont-care" type="NULL"/>
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="SequenceOfData">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="null-data" type="NULL"/>
<xsd:element name="array" type="SequenceOfData"/>
<xsd:element name="structure" type="SequenceOfData"/>
<xsd:element name="boolean" type="xsd:boolean"/>
<xsd:element name="bit-string" type="BitString"/>
<xsd:element name="double-long" type="Integer32"/>
<xsd:element name="double-long-unsigned" type="Unsigned32"/>
<xsd:element name="octet-string" type="xsd:hexBinary"/>
<xsd:element name="visible-string" type="xsd:string"/>
<xsd:element name="utf8-string" type="xsd:string"/>
<xsd:element name="bcd" type="Integer8"/>
<xsd:element name="integer" type="Integer8"/>
<xsd:element name="long" type="Integer16"/>
<xsd:element name="unsigned" type="Unsigned8"/>
<xsd:element name="long-unsigned" type="Unsigned16"/>
<xsd:element name="compact-array">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="contents-description" type="TypeDescription"/>
<xsd:element name="array-contents" type="xsd:hexBinary"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="long64" type="Integer64"/>
<xsd:element name="long64-unsigned" type="Unsigned64"/>
<xsd:element name="enum" type="Unsigned8"/>
<xsd:element name="float32" type="xsd:float"/>
<xsd:element name="float64" type="xsd:double"/>
<xsd:element name="date-time">
<xsd:simpleType>
<xsd:restriction base="xsd:hexBinary">
<xsd:length value="12"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="date">
<xsd:simpleType>
<xsd:restriction base="xsd:hexBinary">
<xsd:length value="5"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="time">
<xsd:simpleType>
<xsd:restriction base="xsd:hexBinary">
<xsd:length value="4"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="dont-care" type="NULL"/>
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="Data">
<xsd:choice>
<xsd:element name="null-data" type="NULL"/>
<xsd:element name="array" type="SequenceOfData"/>
<xsd:element name="structure" type="SequenceOfData"/>
<xsd:element name="boolean" type="xsd:boolean"/>
<xsd:element name="bit-string" type="BitString"/>
<xsd:element name="double-long" type="Integer32"/>
<xsd:element name="double-long-unsigned" type="Unsigned32"/>
<xsd:element name="octet-string" type="xsd:hexBinary"/>
<xsd:element name="visible-string" type="xsd:string"/>
<xsd:element name="utf8-string" type="xsd:string"/>
<xsd:element name="bcd" type="Integer8"/>
<xsd:element name="integer" type="Integer8"/>
<xsd:element name="long" type="Integer16"/>
<xsd:element name="unsigned" type="Unsigned8"/>
<xsd:element name="long-unsigned" type="Unsigned16"/>
<xsd:element name="compact-array">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="contents-description" type="TypeDescription"/>
<xsd:element name="array-contents" type="xsd:hexBinary"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="long64" type="Integer64"/>
<xsd:element name="long64-unsigned" type="Unsigned64"/>
<xsd:element name="enum" type="Unsigned8"/>
<xsd:element name="float32" type="xsd:float"/>
<xsd:element name="float64" type="xsd:double"/>
<xsd:element name="date-time">
<xsd:simpleType>
<xsd:restriction base="xsd:hexBinary">
<xsd:length value="12"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="date">
<xsd:simpleType>
<xsd:restriction base="xsd:hexBinary">
<xsd:length value="5"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="time">
<xsd:simpleType>
<xsd:restriction base="xsd:hexBinary">
<xsd:length value="4"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="dont-care" type="NULL"/>
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="Parameterized-Access">
<xsd:sequence>
<xsd:element name="variable-name" type="ObjectName"/>
<xsd:element name="selector" type="Unsigned8"/>
<xsd:element name="parameter" type="Data"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Block-Number-Access">
<xsd:sequence>
<xsd:element name="block-number" type="Unsigned16"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Read-Data-Block-Access">
<xsd:sequence>
<xsd:element name="last-block" type="xsd:boolean"/>
<xsd:element name="block-number" type="Unsigned16"/>
<xsd:element name="raw-data" type="xsd:hexBinary"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Write-Data-Block-Access">
<xsd:sequence>
<xsd:element name="last-block" type="xsd:boolean"/>
<xsd:element name="block-number" type="Unsigned16"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Variable-Access-Specification">
<xsd:choice>
<xsd:element name="variable-name" type="ObjectName"/>
<xsd:element name="parameterized-access" type="Parameterized-Access"/>
<xsd:element name="block-number-access" type="Block-Number-Access"/>
<xsd:element name="read-data-block-access" type="Read-Data-Block-Access"/>
<xsd:element name="write-data-block-access" type="Write-Data-Block-Access"/>
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="ReadRequest">
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="Variable-Access-Specification" type="Variable-Access-Specification"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="WriteRequest">
<xsd:sequence>
<xsd:element name="variable-access-specification">
<xsd:complexType>
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="Variable-Access-Specification" type="Variable-Access-Specification"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="list-of-data">
<xsd:complexType>
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="Data" type="Data"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="InitiateResponse">
<xsd:sequence>
<xsd:element name="negotiated-quality-of-service" minOccurs="0" type="Integer8"/>
<xsd:element name="negotiated-dlms-version-number" type="Unsigned8"/>
<xsd:element name="negotiated-conformance" type="Conformance"/>
<xsd:element name="server-max-receive-pdu-size" type="Unsigned16"/>
<xsd:element name="vaa-name" type="ObjectName"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Data-Block-Result">
<xsd:sequence>
<xsd:element name="last-block" type="xsd:boolean"/>
<xsd:element name="block-number" type="Unsigned16"/>
<xsd:element name="raw-data" type="xsd:hexBinary"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="ReadResponse">
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="CHOICE">
<xsd:complexType>
<xsd:choice>
<xsd:element name="data" type="Data"/>
<xsd:element name="data-access-error" type="Data-Access-Result"/>
<xsd:element name="data-block-result" type="Data-Block-Result"/>
<xsd:element name="block-number" type="Unsigned16"/>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="WriteResponse">
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="CHOICE">
<xsd:complexType>
<xsd:choice>
<xsd:element name="success" type="NULL"/>
<xsd:element name="data-access-error" type="Data-Access-Result"/>
<xsd:element name="block-number" type="Unsigned16"/>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="ServiceError">
<xsd:choice>
<xsd:element name="application-reference">
<xsd:simpleType>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="other"/>
<xsd:enumeration value="time-elapsed"/>
<xsd:enumeration value="application-unreachable"/>
<xsd:enumeration value="application-reference-invalid"/>
<xsd:enumeration value="application-context-unsupported"/>
<xsd:enumeration value="provider-communication-error"/>
<xsd:enumeration value="deciphering-error"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="hardware-resource">
<xsd:simpleType>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="other"/>
<xsd:enumeration value="memory-unavailable"/>
<xsd:enumeration value="processor-resource-unavailable"/>
<xsd:enumeration value="mass-storage-unavailable"/>
<xsd:enumeration value="other-resource-unavailable"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="vde-state-error">
<xsd:simpleType>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="other"/>
<xsd:enumeration value="no-dlms-context"/>
<xsd:enumeration value="loading-data-set"/>
<xsd:enumeration value="status-nochange"/>
<xsd:enumeration value="status-inoperable"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="service">
<xsd:simpleType>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="other"/>
<xsd:enumeration value="pdu-size"/>
<xsd:enumeration value="service-unsupported"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="definition">
<xsd:simpleType>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="other"/>
<xsd:enumeration value="object-undefined"/>
<xsd:enumeration value="object-class-inconsistent"/>
<xsd:enumeration value="object-attribute-inconsistent"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="access">
<xsd:simpleType>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="other"/>
<xsd:enumeration value="scope-of-access-violated"/>
<xsd:enumeration value="object-access-violated"/>
<xsd:enumeration value="hardware-fault"/>
<xsd:enumeration value="object-unavailable"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="initiate">
<xsd:simpleType>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="other"/>
<xsd:enumeration value="dlms-version-too-low"/>
<xsd:enumeration value="incompatible-conformance"/>
<xsd:enumeration value="pdu-size-too-short"/>
<xsd:enumeration value="refused-by-the-VDE-Handler"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="load-data-set">
<xsd:simpleType>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="other"/>
<xsd:enumeration value="primitive-out-of-sequence"/>
<xsd:enumeration value="not-loadable"/>
<xsd:enumeration value="dataset-size-too-large"/>
<xsd:enumeration value="not-awaited-segment"/>
<xsd:enumeration value="interpretation-failure"/>
<xsd:enumeration value="storage-failure"/>
<xsd:enumeration value="data-set-not-ready"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="task">
<xsd:simpleType>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="other"/>
<xsd:enumeration value="no-remote-control"/>
<xsd:enumeration value="ti-stopped"/>
<xsd:enumeration value="ti-running"/>
<xsd:enumeration value="ti-unusable"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="ConfirmedServiceError">
<xsd:choice>
<xsd:element name="initiateError" type="ServiceError"/>
<xsd:element name="getStatus" type="ServiceError"/>
<xsd:element name="getNameList" type="ServiceError"/>
<xsd:element name="getVariableAttribute" type="ServiceError"/>
<xsd:element name="read" type="ServiceError"/>
<xsd:element name="write" type="ServiceError"/>
<xsd:element name="getDataSetAttribute" type="ServiceError"/>
<xsd:element name="getTIAttribute" type="ServiceError"/>
<xsd:element name="changeScope" type="ServiceError"/>
<xsd:element name="start" type="ServiceError"/>
<xsd:element name="stop" type="ServiceError"/>
<xsd:element name="resume" type="ServiceError"/>
<xsd:element name="makeUsable" type="ServiceError"/>
<xsd:element name="initiateLoad" type="ServiceError"/>
<xsd:element name="loadSegment" type="ServiceError"/>
<xsd:element name="terminateLoad" type="ServiceError"/>
<xsd:element name="initiateUpLoad" type="ServiceError"/>
<xsd:element name="upLoadSegment" type="ServiceError"/>
<xsd:element name="terminateUpLoad" type="ServiceError"/>
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="Notification-Body">
<xsd:sequence>
<xsd:element name="data-value" type="Data"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Data-Notification">
<xsd:sequence>
<xsd:element name="long-invoke-id-and-priority" type="Long-Invoke-Id-And-Priority"/>
<xsd:element name="date-time" type="xsd:hexBinary"/>
<xsd:element name="notification-body" type="Notification-Body"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="UnconfirmedWriteRequest">
<xsd:sequence>
<xsd:element name="variable-access-specification">
<xsd:complexType>
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="Variable-Access-Specification" type="Variable-Access-Specification"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="list-of-data">
<xsd:complexType>
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="Data" type="Data"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="InformationReportRequest">
<xsd:sequence>
<xsd:element name="current-time" minOccurs="0" type="xsd:dateTime"/>
<xsd:element name="variable-access-specification">
<xsd:complexType>
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="Variable-Access-Specification" type="Variable-Access-Specification"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="list-of-data">
<xsd:complexType>
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="Data" type="Data"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Cosem-Attribute-Descriptor">
<xsd:sequence>
<xsd:element name="class-id" type="Cosem-Class-Id"/>
<xsd:element name="instance-id" type="Cosem-Object-Instance-Id"/>
<xsd:element name="attribute-id" type="Cosem-Object-Attribute-Id"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Selective-Access-Descriptor">
<xsd:sequence>
<xsd:element name="access-selector" type="Unsigned8"/>
<xsd:element name="access-parameters" type="Data"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Get-Request-Normal">
<xsd:sequence>
<xsd:element name="invoke-id-and-priority" type="Invoke-Id-And-Priority"/>
<xsd:element name="cosem-attribute-descriptor" type="Cosem-Attribute-Descriptor"/>
<xsd:element name="access-selection" minOccurs="0" type="Selective-Access-Descriptor"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Get-Request-Next">
<xsd:sequence>
<xsd:element name="invoke-id-and-priority" type="Invoke-Id-And-Priority"/>
<xsd:element name="block-number" type="Unsigned32"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Cosem-Attribute-Descriptor-With-Selection">
<xsd:sequence>
<xsd:element name="cosem-attribute-descriptor" type="Cosem-Attribute-Descriptor"/>
<xsd:element name="access-selection" minOccurs="0" type="Selective-Access-Descriptor"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Get-Request-With-List">
<xsd:sequence>
<xsd:element name="invoke-id-and-priority" type="Invoke-Id-And-Priority"/>
<xsd:element name="attribute-descriptor-list">
<xsd:complexType>
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="Cosem-Attribute-Descriptor-With-Selection" type="Cosem-Attribute-Descriptor-With-Selection"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Get-Request">
<xsd:choice>
<xsd:element name="get-request-normal" type="Get-Request-Normal"/>
<xsd:element name="get-request-next" type="Get-Request-Next"/>
<xsd:element name="get-request-with-list" type="Get-Request-With-List"/>
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="Set-Request-Normal">
<xsd:sequence>
<xsd:element name="invoke-id-and-priority" type="Invoke-Id-And-Priority"/>
<xsd:element name="cosem-attribute-descriptor" type="Cosem-Attribute-Descriptor"/>
<xsd:element name="access-selection" minOccurs="0" type="Selective-Access-Descriptor"/>
<xsd:element name="value" type="Data"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="DataBlock-SA">
<xsd:sequence>
<xsd:element name="last-block" type="xsd:boolean"/>
<xsd:element name="block-number" type="Unsigned32"/>
<xsd:element name="raw-data" type="xsd:hexBinary"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Set-Request-With-First-Datablock">
<xsd:sequence>
<xsd:element name="invoke-id-and-priority" type="Invoke-Id-And-Priority"/>
<xsd:element name="cosem-attribute-descriptor" type="Cosem-Attribute-Descriptor"/>
<xsd:element name="access-selection" minOccurs="0" type="Selective-Access-Descriptor"/>
<xsd:element name="datablock" type="DataBlock-SA"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Set-Request-With-Datablock">
<xsd:sequence>
<xsd:element name="invoke-id-and-priority" type="Invoke-Id-And-Priority"/>
<xsd:element name="datablock" type="DataBlock-SA"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Set-Request-With-List">
<xsd:sequence>
<xsd:element name="invoke-id-and-priority" type="Invoke-Id-And-Priority"/>
<xsd:element name="attribute-descriptor-list">
<xsd:complexType>
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="Cosem-Attribute-Descriptor-With-Selection" type="Cosem-Attribute-Descriptor-With-Selection"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="value-list">
<xsd:complexType>
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="Data" type="Data"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Set-Request-With-List-And-First-Datablock">
<xsd:sequence>
<xsd:element name="invoke-id-and-priority" type="Invoke-Id-And-Priority"/>
<xsd:element name="attribute-descriptor-list">
<xsd:complexType>
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="Cosem-Attribute-Descriptor-With-Selection" type="Cosem-Attribute-Descriptor-With-Selection"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="datablock" type="DataBlock-SA"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Set-Request">
<xsd:choice>
<xsd:element name="set-request-normal" type="Set-Request-Normal"/>
<xsd:element name="set-request-with-first-datablock" type="Set-Request-With-First-Datablock"/>
<xsd:element name="set-request-with-datablock" type="Set-Request-With-Datablock"/>
<xsd:element name="set-request-with-list" type="Set-Request-With-List"/>
<xsd:element name="set-request-with-list-and-first-datablock" type="Set-Request-With-List-And-First-Datablock"/>
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="EventNotificationRequest">
<xsd:sequence>
<xsd:element name="time" minOccurs="0" type="xsd:hexBinary"/>
<xsd:element name="cosem-attribute-descriptor" type="Cosem-Attribute-Descriptor"/>
<xsd:element name="attribute-value" type="Data"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Cosem-Method-Descriptor">
<xsd:sequence>
<xsd:element name="class-id" type="Cosem-Class-Id"/>
<xsd:element name="instance-id" type="Cosem-Object-Instance-Id"/>
<xsd:element name="method-id" type="Cosem-Object-Method-Id"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Action-Request-Normal">
<xsd:sequence>
<xsd:element name="invoke-id-and-priority" type="Invoke-Id-And-Priority"/>
<xsd:element name="cosem-method-descriptor" type="Cosem-Method-Descriptor"/>
<xsd:element name="method-invocation-parameters" minOccurs="0" type="Data"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Action-Request-Next-Pblock">
<xsd:sequence>
<xsd:element name="invoke-id-and-priority" type="Invoke-Id-And-Priority"/>
<xsd:element name="block-number" type="Unsigned32"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Action-Request-With-List">
<xsd:sequence>
<xsd:element name="invoke-id-and-priority" type="Invoke-Id-And-Priority"/>
<xsd:element name="cosem-method-descriptor-list">
<xsd:complexType>
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="Cosem-Method-Descriptor" type="Cosem-Method-Descriptor"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="method-invocation-parameters">
<xsd:complexType>
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="Data" type="Data"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Action-Request-With-First-Pblock">
<xsd:sequence>
<xsd:element name="invoke-id-and-priority" type="Invoke-Id-And-Priority"/>
<xsd:element name="cosem-method-descriptor" type="Cosem-Method-Descriptor"/>
<xsd:element name="pblock" type="DataBlock-SA"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Action-Request-With-List-And-First-Pblock">
<xsd:sequence>
<xsd:element name="invoke-id-and-priority" type="Invoke-Id-And-Priority"/>
<xsd:element name="cosem-method-descriptor-list">
<xsd:complexType>
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="Cosem-Method-Descriptor" type="Cosem-Method-Descriptor"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="pblock" type="DataBlock-SA"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Action-Request-With-Pblock">
<xsd:sequence>
<xsd:element name="invoke-id-and-priority" type="Invoke-Id-And-Priority"/>
<xsd:element name="pblock" type="DataBlock-SA"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Action-Request">
<xsd:choice>
<xsd:element name="action-request-normal" type="Action-Request-Normal"/>
<xsd:element name="action-request-next-pblock" type="Action-Request-Next-Pblock"/>
<xsd:element name="action-request-with-list" type="Action-Request-With-List"/>
<xsd:element name="action-request-with-first-pblock" type="Action-Request-With-First-Pblock"/>
<xsd:element name="action-request-with-list-and-first-pblock" type="Action-Request-With-List-And-First-Pblock"/>
<xsd:element name="action-request-with-pblock" type="Action-Request-With-Pblock"/>
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="Get-Data-Result">
<xsd:choice>
<xsd:element name="data" type="Data"/>
<xsd:element name="data-access-result" type="Data-Access-Result"/>
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="Get-Response-Normal">
<xsd:sequence>
<xsd:element name="invoke-id-and-priority" type="Invoke-Id-And-Priority"/>
<xsd:element name="result" type="Get-Data-Result"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="DataBlock-G">
<xsd:sequence>
<xsd:element name="last-block" type="xsd:boolean"/>
<xsd:element name="block-number" type="Unsigned32"/>
<xsd:element name="result">
<xsd:complexType>
<xsd:choice>
<xsd:element name="raw-data" type="xsd:hexBinary"/>
<xsd:element name="data-access-result" type="Data-Access-Result"/>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Get-Response-With-Datablock">
<xsd:sequence>
<xsd:element name="invoke-id-and-priority" type="Invoke-Id-And-Priority"/>
<xsd:element name="result" type="DataBlock-G"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Get-Response-With-List">
<xsd:sequence>
<xsd:element name="invoke-id-and-priority" type="Invoke-Id-And-Priority"/>
<xsd:element name="result">
<xsd:complexType>
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="Get-Data-Result" type="Get-Data-Result"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Get-Response">
<xsd:choice>
<xsd:element name="get-response-normal" type="Get-Response-Normal"/>
<xsd:element name="get-response-with-datablock" type="Get-Response-With-Datablock"/>
<xsd:element name="get-response-with-list" type="Get-Response-With-List"/>
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="Set-Response-Normal">
<xsd:sequence>
<xsd:element name="invoke-id-and-priority" type="Invoke-Id-And-Priority"/>
<xsd:element name="result" type="Data-Access-Result"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Set-Response-Datablock">
<xsd:sequence>
<xsd:element name="invoke-id-and-priority" type="Invoke-Id-And-Priority"/>
<xsd:element name="block-number" type="Unsigned32"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Set-Response-Last-Datablock">
<xsd:sequence>
<xsd:element name="invoke-id-and-priority" type="Invoke-Id-And-Priority"/>
<xsd:element name="result" type="Data-Access-Result"/>
<xsd:element name="block-number" type="Unsigned32"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Set-Response-Last-Datablock-With-List">
<xsd:sequence>
<xsd:element name="invoke-id-and-priority" type="Invoke-Id-And-Priority"/>
<xsd:element name="result">
<xsd:simpleType>
<xsd:list itemType="Data-Access-Result"/>
</xsd:simpleType>
</xsd:element>
<xsd:element name="block-number" type="Unsigned32"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Set-Response-With-List">
<xsd:sequence>
<xsd:element name="invoke-id-and-priority" type="Invoke-Id-And-Priority"/>
<xsd:element name="result">
<xsd:simpleType>
<xsd:list itemType="Data-Access-Result"/>
</xsd:simpleType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Set-Response">
<xsd:choice>
<xsd:element name="set-response-normal" type="Set-Response-Normal"/>
<xsd:element name="set-response-datablock" type="Set-Response-Datablock"/>
<xsd:element name="set-response-last-datablock" type="Set-Response-Last-Datablock"/>
<xsd:element name="set-response-last-datablock-with-list" type="Set-Response-Last-Datablock-With-List"/>
<xsd:element name="set-response-with-list" type="Set-Response-With-List"/>
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="Action-Response-With-Optional-Data">
<xsd:sequence>
<xsd:element name="result" type="Action-Result"/>
<xsd:element name="return-parameters" minOccurs="0" type="Get-Data-Result"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Action-Response-Normal">
<xsd:sequence>
<xsd:element name="invoke-id-and-priority" type="Invoke-Id-And-Priority"/>
<xsd:element name="single-response" type="Action-Response-With-Optional-Data"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Action-Response-With-Pblock">
<xsd:sequence>
<xsd:element name="invoke-id-and-priority" type="Invoke-Id-And-Priority"/>
<xsd:element name="pblock" type="DataBlock-SA"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Action-Response-With-List">
<xsd:sequence>
<xsd:element name="invoke-id-and-priority" type="Invoke-Id-And-Priority"/>
<xsd:element name="list-of-responses">
<xsd:complexType>
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="Action-Response-With-Optional-Data" type="Action-Response-With-Optional-Data"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Action-Response-Next-Pblock">
<xsd:sequence>
<xsd:element name="invoke-id-and-priority" type="Invoke-Id-And-Priority"/>
<xsd:element name="block-number" type="Unsigned32"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Action-Response">
<xsd:choice>
<xsd:element name="action-response-normal" type="Action-Response-Normal"/>
<xsd:element name="action-response-with-pblock" type="Action-Response-With-Pblock"/>
<xsd:element name="action-response-with-list" type="Action-Response-With-List"/>
<xsd:element name="action-response-next-pblock" type="Action-Response-Next-Pblock"/>
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="ExceptionResponse">
<xsd:sequence>
<xsd:element name="state-error">
<xsd:simpleType>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="service-not-allowed"/>
<xsd:enumeration value="service-unknown"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="service-error">
<xsd:complexType>
<xsd:choice>
<xsd:element name="operation-not-possible" type="NULL"/>
<xsd:element name="service-not-supported" type="NULL"/>
<xsd:element name="other-reason" type="NULL"/>
<xsd:element name="pdu-too-long" type="NULL"/>
<xsd:element name="deciphering-error" type="NULL"/>
<xsd:element name="invocation-counter-error" type="Unsigned32"/>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Access-Request-Get">
<xsd:sequence>
<xsd:element name="cosem-attribute-descriptor" type="Cosem-Attribute-Descriptor"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Access-Request-Set">
<xsd:sequence>
<xsd:element name="cosem-attribute-descriptor" type="Cosem-Attribute-Descriptor"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Access-Request-Action">
<xsd:sequence>
<xsd:element name="cosem-method-descriptor" type="Cosem-Method-Descriptor"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Access-Request-Get-With-Selection">
<xsd:sequence>
<xsd:element name="cosem-attribute-descriptor" type="Cosem-Attribute-Descriptor"/>
<xsd:element name="access-selection" type="Selective-Access-Descriptor"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Access-Request-Set-With-Selection">
<xsd:sequence>
<xsd:element name="cosem-attribute-descriptor" type="Cosem-Attribute-Descriptor"/>
<xsd:element name="access-selection" type="Selective-Access-Descriptor"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Access-Request-Specification">
<xsd:choice>
<xsd:element name="access-request-get" type="Access-Request-Get"/>
<xsd:element name="access-request-set" type="Access-Request-Set"/>
<xsd:element name="access-request-action" type="Access-Request-Action"/>
<xsd:element name="access-request-get-with-selection" type="Access-Request-Get-With-Selection"/>
<xsd:element name="access-request-set-with-selection" type="Access-Request-Set-With-Selection"/>
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="List-Of-Access-Request-Specification">
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="Access-Request-Specification" type="Access-Request-Specification"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="List-Of-Data">
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="Data" type="Data"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Access-Request-Body">
<xsd:sequence>
<xsd:element name="access-request-specification" type="List-Of-Access-Request-Specification"/>
<xsd:element name="access-request-list-of-data" type="List-Of-Data"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Access-Request">
<xsd:sequence>
<xsd:element name="long-invoke-id-and-priority" type="Long-Invoke-Id-And-Priority"/>
<xsd:element name="date-time" type="xsd:hexBinary"/>
<xsd:element name="access-request-body" type="Access-Request-Body"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Access-Response-Get">
<xsd:sequence>
<xsd:element name="result" type="Data-Access-Result"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Access-Response-Set">
<xsd:sequence>
<xsd:element name="result" type="Data-Access-Result"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Access-Response-Action">
<xsd:sequence>
<xsd:element name="result" type="Action-Result"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Access-Response-Specification">
<xsd:choice>
<xsd:element name="access-response-get" type="Access-Response-Get"/>
<xsd:element name="access-response-set" type="Access-Response-Set"/>
<xsd:element name="access-response-action" type="Access-Response-Action"/>
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="List-Of-Access-Response-Specification">
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="Access-Response-Specification" type="Access-Response-Specification"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Access-Response-Body">
<xsd:sequence>
<xsd:element name="access-request-specification" minOccurs="0" type="List-Of-Access-Request-Specification"/>
<xsd:element name="access-response-list-of-data" type="List-Of-Data"/>
<xsd:element name="access-response-specification" type="List-Of-Access-Response-Specification"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Access-Response">
<xsd:sequence>
<xsd:element name="long-invoke-id-and-priority" type="Long-Invoke-Id-And-Priority"/>
<xsd:element name="date-time" type="xsd:hexBinary"/>
<xsd:element name="access-response-body" type="Access-Response-Body"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="General-Glo-Ciphering">
<xsd:sequence>
<xsd:element name="system-title" type="xsd:hexBinary"/>
<xsd:element name="ciphered-content" type="xsd:hexBinary"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="General-Ded-Ciphering">
<xsd:sequence>
<xsd:element name="system-title" type="xsd:hexBinary"/>
<xsd:element name="ciphered-content" type="xsd:hexBinary"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Identified-Key">
<xsd:sequence>
<xsd:element name="key-id" type="Key-Id"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Wrapped-Key">
<xsd:sequence>
<xsd:element name="kek-id" type="Kek-Id"/>
<xsd:element name="key-ciphered-data" type="xsd:hexBinary"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Agreed-Key">
<xsd:sequence>
<xsd:element name="key-parameters" type="xsd:hexBinary"/>
<xsd:element name="key-ciphered-data" type="xsd:hexBinary"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Key-Info">
<xsd:choice>
<xsd:element name="identified-key" type="Identified-Key"/>
<xsd:element name="wrapped-key" type="Wrapped-Key"/>
<xsd:element name="agreed-key" type="Agreed-Key"/>
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="General-Ciphering">
<xsd:sequence>
<xsd:element name="transaction-id" type="xsd:hexBinary"/>
<xsd:element name="originator-system-title" type="xsd:hexBinary"/>
<xsd:element name="recipient-system-title" type="xsd:hexBinary"/>
<xsd:element name="date-time" type="xsd:hexBinary"/>
<xsd:element name="other-information" type="xsd:hexBinary"/>
<xsd:element name="key-info" minOccurs="0" type="Key-Info"/>
<xsd:element name="ciphered-content" type="xsd:hexBinary"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="General-Signing">
<xsd:sequence>
<xsd:element name="transaction-id" type="xsd:hexBinary"/>
<xsd:element name="originator-system-title" type="xsd:hexBinary"/>
<xsd:element name="recipient-system-title" type="xsd:hexBinary"/>
<xsd:element name="date-time" type="xsd:hexBinary"/>
<xsd:element name="other-information" type="xsd:hexBinary"/>
<xsd:element name="content" type="xsd:hexBinary"/>
<xsd:element name="signature" type="xsd:hexBinary"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="General-Block-Transfer">
<xsd:sequence>
<xsd:element name="block-control" type="Block-Control"/>
<xsd:element name="block-number" type="Unsigned16"/>
<xsd:element name="block-number-ack" type="Unsigned16"/>
<xsd:element name="block-data" type="xsd:hexBinary"/>
</xsd:sequence>
</xsd:complexType>
本文来自博客园,作者:{施林峰},转载请注明原文链接:https://www.cnblogs.com/shilinfeng/p/17871020.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具