DLMS COSEM 数据对象 与 ASN.1 BER 编码 —— 详解一览
什么是 ASN.1?
ASN.1 编码是通信协议中非常重要的一种数据表示和传输方式,尤其在 DLMS/COSEM、SNMP、X.509、TLS 等标准中大量使用。
ASN.1 全称是 Abstract Syntax Notation One(抽象语法标记语言第一版)
它是一种描述数据结构的语言,不是编码方法,而是规范一种“数据结构的定义方式”。
✨ 类似 XML / JSON 是描述数据的格式,ASN.1 是更底层、适合机器传输的那种。
📦 什么是 ASN.1 编码?
ASN.1 编码定义了如何把 ASN.1 描述的结构转换为二进制格式传输。
其中最常见的编码规则是:
编码规则 | 全称 | 特点 |
---|---|---|
BER | Basic Encoding Rules | 最常用、结构灵活,DLMS/COSEM 采用此格式 |
DER | Distinguished ER | BER 的简化版,应用于证书等(如 X.509) |
PER | Packed ER | 高压缩率,用于无线通信 |
🧪 ASN.1 BER 编码格式:TLV(三段式)
[TAG] [LENGTH] [VALUE]
各部分说明:
部分 | 说明 |
---|---|
TAG | 表示数据类型,如 INTEGER、STRING、SEQUENCE 等 |
LENGTH | 表示 VALUE 的长度,支持短格式(1字节)或长格式(多字节) |
VALUE | 实际的数据内容(如数字、字符串、结构等) |
🎯 常见 ASN.1 Tag 值示例
类型 | TAG (十六进制) | 含义 |
---|---|---|
BOOLEAN | 01 | 布尔值 |
INTEGER | 02 | 整数 |
OCTET STRING | 04 | 字节串(如密码、密钥等) |
NULL | 05 | 空值 |
OBJECT IDENTIFIER | 06 | 对象标识符(协议ID等) |
SEQUENCE | 30 | 结构体封装(构造类型) |
📘 示例:AARQ 报文中的 ASN.1 编码
30 1A 02 01 01 04 10 4D 4C 4D 00 00 00 00 01 23 45 67 89 AB CD EF
解码说明:
字节序列 | 含义 |
---|---|
30 | SEQUENCE |
1A | 长度 26 字节 |
02 01 01 | INTEGER,值为 1 |
04 10 ... | OCTET STRING,16 字节系统标题 |
📌 应用场景(DLMS/COSEM 相关)
场景 | 使用 ASN.1 编码部分 |
---|---|
AARQ / AARE 报文 | 建立 AA,封装用户安全上下文 |
加密载荷 Ciphered Payload | 加密前的结构体需 ASN.1 封装 |
安全设置中定义认证机制 | 使用 OBJECT IDENTIFIER 编码 |
注册协议(如 CIASE) | 包装注册结构体 |
✅ 特点总结
特点 | 说明 |
---|---|
灵活性高 | 支持多种结构体嵌套 |
结构清晰 | 易于层级封装,例如 SEQUENCE + 子字段 |
协议通用性强 | 适用于各种通信协议,如 SNMP、TLS、DLMS |
不易手工编写 | 通常需工具(如 Wireshark、ASN.1 Viewer)辅助解析 |
🎯 总结:
ASN.1 是结构化的语言,BER 是它的“口语表达”。
它在 DLMS 中用于封装安全上下文和握手结构,和 COSEM 数据类型不一样,COSEM 更偏向具体的值,ASN.1 更偏向结构和权限表达。
什么是 COSEM 数据模型 ?
在 DLMS 协议中,COSEM 编码是一种用于表示设备数据模型(COSEM 对象模型)中数据的结构化编码方式。它主要用于封装数据内容,如对象属性值、方法参数和返回值等。
📚 1. 什么是 COSEM?
COSEM 全称是 Companion Specification for Energy Metering,是 DLMS 协议的核心组成部分,用于描述“电表或设备的数据模型”和“通信结构”。
COSEM 对象由:
- OBIS(对象标识符)
- 属性(如数值、电压等)
- 方法(操作,如复位、设置等)组成。
🔧 2. 什么是 COSEM 编码?
COSEM 编码是指 DLMS 协议中使用的一套数据类型编码规则,用于对上述对象的数据进行序列化,供传输使用。它不是 ASN.1 的 BER 编码,但有相似的结构,是为电表通信量身定制的一种轻量级类型编码方案。
🧩 3. COSEM 数据类型及编码规则(Tag-Based)
COSEM 使用 “类型 + 长度 + 值”的结构,类似 TLV(Tag-Length-Value),如下:
Tag(类型标记) | 类型名称 | 示例用途 |
---|---|---|
00 | NULL_DATA | 空值 |
01 | ARRAY | 数组(如多个表值) |
02 | STRUCTURE | 结构体 |
03 | BOOLEAN | true/false |
04 | BIT STRING | 位数据 |
09 | OCTET STRING | 字节串 |
0A | VISIBLE STRING | 字符串(UTF8) |
10 | INTEGER | 有符号整数 |
11 | LONG | 有符号 16 位整数 |
12 | UNSIGNED | 无符号 8 位整数 |
06 | DOUBLE LONG | 有符号 32 位整数 |
16 | LONG64 | 有符号 64 位整数 |
17 | UNSIGNED64 | 无符号 64 位整数 |
… | 其他 |
🎯 COSEM 数据类型由
DLMS UA 1000-1
标准定义,用于编码对象属性数据等。
📦 4. COSEM 编码 vs ASN.1 编码:区别一览
特性 | COSEM 编码 | ASN.1 (BER) 编码 |
---|---|---|
用途 | 设备数据模型的数据表示 | 安全结构(如 AARQ、AARE、认证)封装 |
编码结构 | 轻量级 TLV(Tag + Len + Value) | 标准 TLV,支持复杂结构和类标记 |
编码复杂度 | 简单,定制 | 通用,结构化 |
是否可嵌套结构体 | 支持结构体、数组 | 更强结构表达(SEQUENCE, SET) |
示例应用 | 属性读取响应、设置请求、方法调用 | 安全上下文、握手、注册信息等 |
🧪 5. 报文例子(COSEM 编码)
02 03 09 06 01 00 1F 07 00 FF -- Octet String (OBIS)0F 00 -- Integer: 012 01 -- Unsigned: 1
解释:
Byte | 含义 |
---|---|
02 | STRUCTURE 类型 |
03 | 结构体含 3 个字段 |
09 06 ... | 第 1 个字段:Octet String,长度 6(OBIS) |
0F 00 | 第 2 个字段:Integer,值为 0 |
12 01 | 第 3 个字段:Unsigned,值为 1 |
💡 总结一句话:
COSEM 编码 是 DLMS 协议中专用于编码电能表设备数据模型(如属性值、操作参数)的数据表示方式,以 TLV 格式封装各种基本数据类型,与 ASN.1 编码分别服务于数据层 vs 安全层。
DLMS COSEM 数据对象 与 ASN.1/BER
在 DLMS/COSEM 协议中,经常会遇到两种不同的编码规范:COSEM 数据类型编码 和 ASN.1 BER 编码。这两者虽然在结构上都使用 TLV(Tag-Length-Value)格式,但它们的作用、使用场景、编码规则和数据类型编号都不一样。
🧩 一、COSEM 数据类型编码(也称 DLMS 数据类型)
✅ 作用:
用于表示 COSEM 对象模型中的属性值或参数值,常见于:
- GET/SET 请求与响应报文体
- Action 请求参数
- Profile Generic 的数据结构
📦 编码结构(TLV):
[Tag] [Length] [Value]
🏷 常见 Tag 值(数据类型):
数据类型 | Tag (Hex) | 示例说明 |
---|---|---|
NULL | 00 | 无值 |
ARRAY | 01 | 用于封装一个数据项数组 |
STRUCTURE | 02 | 用于封装结构体类型的数据 |
BOOLEAN | 03 | 布尔值 |
INTEGER | 0F | 有符号整型(8位) |
UNSIGNED | 11 | 无符号整型(8位) |
LONG | 10 | 有符号整型(16位) |
UNSIGNED LONG | 12 | 无符号整型(16位) |
OCTET STRING | 09 | 字节序列 |
VISIBLE STRING | 0A | 可打印字符 |
BCD | 13 | 二进制编码十进制 |
ENUM | 16 | 枚举类型 |
LONG64 | 14 | 有符号整型(64位) |
📍 应用场景:
- DLMS 服务层:如 Get-Request, Set-Request, Action-Request 的数据体
- Profile Generic 表格值
- 普通读写数据交换
🧬 二、ASN.1 BER 编码(Basic Encoding Rules)
✅ 作用:
ASN.1 是一种描述数据结构的抽象语法,由 BER 进行具体编码。DLMS 用它在高层协议封装中描述 Application Association(AA)建立过程中的数据结构。
📦 编码结构(TLV):
[Tag] [Length] [Value]
但它的 Tag 更加复杂(支持 Class + Primitive/Constructed + TagNumber)
🏷 常见 Tag 值(通用类):
ASN.1 数据类型 | Tag (Hex) | 类别 | 示例用途 |
---|---|---|---|
INTEGER | 02 | 原始/通用 | 各种标识、版本号等 |
OCTET STRING | 04 | 原始/通用 | System Title、密码等 |
OBJECT IDENTIFIER | 06 | 原始/通用 | 协议标识符 |
SEQUENCE | 30 | 构造/通用 | AARQ 报文中 user-info 包含结构 |
BOOLEAN | 01 | 原始/通用 | 表示 true/false |
📍 应用场景:
- Application Association(AA)建立过程:AARQ / AARE 报文
- Security context 封装(如 ciphered payload)
- 设备注册协议(CIASE)数据结构
🔍 三、如何快速区分这两种编码?
比较项 | COSEM 数据类型编码 | ASN.1 BER 编码 |
---|---|---|
使用场景 | GET/SET/Action 交互数据 | AARQ/AARE、加密封装、注册协议等 |
编码标准 | DLMS UA 规范定义 | ISO 8825 BER |
Tag 值特点 | 多以 0x01~0x16 表示常见类型 | 常见有 0x04 , 0x06 , 0x30 等 |
Tag 对应含义 | 映射到 COSEM 类型 | 映射到 ASN.1 数据结构 |
示例 | 09 06 01 02 03 04 05 06 | 04 06 01 02 03 04 05 06 |
是否支持结构嵌套 | 是(Structure、Array) | 是(Sequence、Set) |
是否常用于加密封装 | 否(加密后体才用它) | 是(加密体、系统标题、认证码) |
📌 补充示意图:协议使用栈
+----------------------+| ASN.1 编码(AARQ) | ← 安全上下文封装、系统标题、认证数据+----------------------+| COSEM/DLMS 应用层 | ← Get/Set/Action 请求结构+----------------------+| HDLC/Wrapper 层 | ← 报文传输、帧头帧尾+----------------------+
🧠 总结记忆口诀:
- COSEM编码在“内容”层,表征属性的数据类型
- ASN.1 编码在“封装”层,服务交互或加密用结构体
📦 DLMS 报文中 COSEM 编码 vs ASN.1 编码对比
📌 场景说明:
以下两个典型场景:
- 场景一(COSEM 编码):读取一个对象的属性,比如读取设备名称(Visible String)
- 场景二(ASN.1 编码):AARQ 报文中携带
System Title
,用于安全上下文初始化
🧪 报文一:COSEM 数据类型编码(例如 GET Response)
09 0C 44 4C 4D 53 5F 44 45 56 49 43 45 5F 31
🔍 解码:
字节 | 含义 |
---|---|
09 | 数据类型:Octet String |
0C | 数据长度:12 字节 |
44...31 | 数据内容:“DLMS_DEVICE_1” |
✅ 使用场景:读取对象属性,比如设备名称、序列号等。
✅ 位置:DLMS 的 Get-Response-PDU 中的数据体。
🧪 报文二:ASN.1 BER 编码(例如 AARQ user-information)
04 10 4D 4C 4D 00 00 00 00 01 23 45 67 89 AB CD EF
🔍 解码:
字节 | 含义 |
---|---|
04 | ASN.1 数据类型:Octet String |
10 | 数据长度:16 字节 |
4D...EF | 内容:System Title,含制造商 ID + 唯一标识 |
✅ 使用场景:建立应用关联(AA),用于加密会话身份识别。
✅ 位置:AARQ APDU 中的 user-information 字段里。
🎯 图解对比
【COSEM 编码】
Get Response PDU:
+----------+-----------+------------------------+
| Tag=09 | Length=0C | Value="DLMS_DEVICE_1" |
+----------+-----------+------------------------+【ASN.1 编码】
AARQ User Info:
+----------+-----------+------------------------+
| Tag=04 | Length=10 | Value=System Title |
+----------+-----------+------------------------+
🧠 总结对照表
项目 | COSEM 数据体编码 | ASN.1 BER 编码 |
---|---|---|
编码标准 | DLMS UA 1000-1 Part 2 | ISO/IEC 8825 (BER) |
使用场景 | 属性值读写、参数传输 | 应用层握手、注册、安全上下文 |
示例 Tag | 09 (Octet String) | 04 (Octet String) |
示例长度与内容 | 09 0C ... | 04 10 ... |
是否表示结构体/对象 | 是(Array/Structure) | 是(Sequence/Set) |
区分 COSEM 数据类型编码 与 ASN.1 BER 编码 是理解 DLMS 协议报文结构的关键。它们虽然都采用 TLV(Tag-Length-Value)格式,但应用场景、语义和 Tag 值完全不同。
✅ 一张表快速区分 COSEM 编码 vs ASN.1 编码
比较项 | COSEM 数据类型编码 | ASN.1 BER 编码 |
---|---|---|
📌 使用位置 | 报文的数据部分,用于传输对象属性值 | 报文的封装头部/结构部分,如 AARQ/AARE |
🔐 作用 | 表达 DLMS 数据模型的具体值类型 | 封装 AA 信息、安全上下文,进行结构化表达 |
📦 典型数据体 | Get-Response-Data 、Set-Request-With-Data | AARQ , AARE , Security Payload |
🏷 Tag 举例 | 01 (Array), 02 (Structure), 09 (Octet String) | 04 (Octet String), 06 (OID), 30 (SEQUENCE) |
📜 编码规范 | DLMS UA 1000-1 Part 2(DLMS定义) | ASN.1 BER(ISO/IEC 8825) |
🧠 解码思路 | 值本身,表示实际对象的数据 | 封装结构,表示"谁"、“怎么封装”、“结构层级” |
🧪 Tag 识别规律 | 多在 0x01 ~ 0x16 区间 | 常见 0x04 、0x06 、0x30 、0xA1 等 |
🚩 常见入口字段 | Get-Response-With-Data , Set-Request-With-Data | AARQ , AARE , user-information |
📚 是否结构化嵌套 | 通过 STRUCTURE / ARRAY 实现 | 通过 SEQUENCE / SET 实现 |
📌 常见字符串编码 tag | 0x09 = Octet String | 0x04 = Octet String |
🔍 快速实战判断方法
✅ 看上下文:
- 报文是 业务数据交互(Get/Set/Action)?→ COSEM 编码
- 报文是 连接认证/握手/加密数据封装?→ ASN.1 编码
✅ 看字段位置:
- 出现在
AARQ / AARE / AssociationRequest
? → ASN.1 - 出现在
GetResponseNormal
里面? → COSEM
✅ 看 Tag 值:
Tag 值 | 可能代表 | 属于哪个编码 |
---|---|---|
0x09 | Octet String | COSEM |
0x04 | Octet String (ASN.1) | ASN.1 |
0x30 | SEQUENCE | ASN.1 |
0x01 | Array | COSEM |
0x02 | Structure | COSEM |
🧪 示例对比
🟩 COSEM 示例
09 06 01 02 03 04 05 06
09
= Octet String06
= 长度- 后续为 6 字节内容
✅ 表示读取了某个对象属性,COSEM 格式
🟦 ASN.1 示例
04 10 4D 4C 4D 00 00 00 00 01 23 45 67 89 AB CD EF
04
= ASN.1 的 Octet String10
= 长度为 16 字节
✅ 表示 system title 封装在 AARQ 中,ASN.1 格式
🎯 总结口诀(超实用):
业务值交互用 COSEM,结构封装握手看 ASN.1;0x09 是 Octet,封装里看 0x04;Get/Set 是数据,AARQ 是握手。