面向对象的用电信息数据交换协议
国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802
前言:
排版 by Dr_Ting
公众号:庭说
移步 tingtalk.me 获得更友好的阅读体验
Q/GDW XXXX-201X《面向对象的用电信息数据交换协议》是根据《国家电网公司关于下达 2017 年度公司第一批技术标准制修订计划的通知》(国家电网科﹝2017﹞72 号)的要求,制订面向对象的用电信息数据交换协议。
- 本标准依据GB/T 1.1-2009给出的规则起草。
- 本标准由国家电网公司营销部提出并负责解释。
- 本标准由国家电网公司科技部归口。
范围
本标准规定了用电信息数据交换协议的通信架构、数据链路层、应用层、接口类与对象标识。
本标准适用于用电信息采集系统主站(以下简称“主站”)、采集终端、电能表之间采用点对点、多点共线及一点对多点通信方式的通信数据交换。
规范性引用文件
下列文件对于本文件的应用是必不可少的。凡是注日期的引用文件,仅所注日期的版本适用于本文件。凡是不注日期的引用文件,其最新版本(包括所有的修改单)适用于本文件。
- GB/T 16262.1-2006 信息技术 抽象语法记法(ASN.1) 第 1 部分 基本记法规范
- GB/T 17966-2000 微处理器系统的二进制浮点运算
- CJ/T 188-2004 户用计量仪表数据传输技术条件
- DL/T 645-2007 多功能电能表通信协议
- DL/T 790.6-2010 采用配电线载波系统的配电自动化 第 6 部分 A-XDR 编码规则
术语、定义和缩略语
术语和定义
面向对象的用电信息数据交换协议
object oriented electic data exchange protocol
基于面向对象建模方法建立的一套适用于用电信息采集系统的互操作性协议。面向对象建模以接口类实现继承关系,以对象来封装数据及操作,以对象为互操作的基本要素。
对象标识
object identification
标识终端中对象唯一名称的编码。
逻辑名
logical name
用于标识接口类的实例,它是接口类的第一个属性,它的值与对象标识一致。
类标识码
class id
用于区别对象接口类的标识码,即接口类的名称。
服务器地址
server address
客户机/服务器(Client/Server)访问模型中的服务器(Server)的通信地址。
逻辑地址
logic address
终端的服务器模型中逻辑设备的地址。
客户机地址
client address
客户机/服务器(Client/Server)访问模型中的客户机(Client)的通信地址。
主站访问采集终端时,采集终端为服务器,主站为客户机;主站访问电能表时,电能表为服务器,主站为客户机;采集终端访问电能表时,电能表为服务器,采集终端为客户机。
采集启动时标
acquisition start time
启动一次采集任务时的设备时钟当前值,其值只与启动时刻有关,与执行的时间长短无关。
注:acquisition [ˌækwi'ziʃn](知识、技能等的)获得,得到
采集成功时标
acquisition time
客户机成功接收到服务器响应时的设备时钟当前值。
采集存储时标
acquisition storage time
采集到的数据进行存储的时间。
采集规则
acquisition rules
描述采集终端采集的数据的内容及其对应关系。
组地址
group address
具有某一相同属性的设备群组编码,如属于同一行业,同一变电站,同一线路,可以响应同一个命令。
通配地址
the wildcard address
在十进制编码表示的地址码中出现一位或多位采用了通配符的地址码。
注:wildcard 通配符。
消息鉴别码
message authentication code
用于鉴别消息的完整性固定长度认证标识。
注:authentication [ɔː,θentɪ'keɪʃən] 证明;鉴定;证实
符号和缩略语
符号和缩略语 | 全文 | 表示 |
---|---|---|
A | Address | 地址域 |
ACD | Ask Call Demand | 请求访问标志 |
AD | Acquired Data | 采集数据 |
APDU | Application Layer Protocol Data Unit | 应用层协议数据单元 |
A-XDR | Adapted Extended Data Representation | 可调整的扩展数据表示 |
B | Binary | 二进制 |
CA | Client Address | 客户机通信地址 |
CSD | Column Selection Descriptor | 列选择描述符 |
DAR | Data Access Result | 数据访问结果 |
DIR | Direction | 传输方向位 |
ESAM | Embedded Secure Access Module | 嵌入式安全控制模块 |
FCS | Frame Check Sum | 帧校验 |
H | Hex | 十六进制 |
HCS | Head Check Sum | 帧头校验 |
IC | Interface Class | 接口类 |
LSB | Least Significant Bit | 最低有效位 |
MAC | Message Authentication Code | 消息鉴别码 |
MS | Meter Set | 电能表集合 |
OAD | Object Attribute Descriptor | 对象属性描述符 |
OI | Object Identify | 对象标识 |
OMD | Object Method Descriptort | 对象方法描述符 |
PIID | Priority and Invoke ID | 序号及优先标志 |
PIID-ACD | Priority and Invoke ID with ACD | 带请求访问标志的序号及优先标志 |
PRM | Primary Request Message | 启动标志位 |
RCSD | Record Column Selection Descriptor | 记录列选择描述符 |
RN | Random Numbers | 随机数 |
ROAD | Record Object Attribute Descriptor | 记录型对象属性描述符 |
RSD | Record Selection Descriptor | 记录选择描述符 |
SA | Server Address | 服务器通信地址 |
SC | Scrambling Code | 扰码 |
TI | Time Interval | 时间间隔 |
TSA | Target Server Address | 目标服务器地址 |
∷= | 定义为 |
注 1: attribute ['ætribju:t] 属性;性质;特征;Patience is one of the most important attributes in a teacher.
注 2: invoke [ɪnˈvəʊk] 提出或授引……以支持或证明
通信架构
信息交换模型
客户机和服务器的应用进程分别位于不同的设备,它们的信息交换
借助于通信协议实现。信息交换模型如下图:
客户机和服务器的应用使用最高层协议的服务,所以应用层是唯一包含服务组件的协议层,应用层协议数据单元(APDU)通过数据链路层协议传输帧的链路用户数据域传输。
面向应用连接的数据交换
本标准是面向应用连接的数据交换协议,数据交换过程如下图:
客户机和服务器在开始通信前,通信信道必须先完成预连接。预连接建立后,默认具有一个最低权限的应用连接,客户机和服务器之间可直接进行数据交换。当客户机需要得到较高权限的服务器服务时,客户机必须发起建立较高权限的应用连接。
请求/响应类型的数据交换
本标准支持客户机应用进程向服务器应用进程提出服务请求,服务器应用进程向客户机应用进程提供远程服务响应。
通知/确认类型的数据交换
本标准支持服务器应用进程根据客户机预先定制的主动上报内容,向客户机应用进程提供远程主动上报数据服务,客户机应用进程向服务器应用进程回复服务确认。
服务器模型
- 逻辑设备 0
- 应用连接对象 0(预先建立的)
- 应用连接对象 1
- 应用连接对象 n
- 其他接口类对象 1
- 其他接口类对象 2
- 其他接口类对象 n
- 逻辑设备 1
- 逻辑设备 2
- 逻辑设备 3
物理设备由若干逻辑设备(最多 4 个)构成,每个逻辑设备由若干可访问的接口类对象构成,包括一个预先建立的应用连接对象、若干个应用连接对象、若干个其他接口类对象。
- 逻辑设备 0 为必须具备的逻辑设备
- 对于带交采的终端
- 逻辑设备 0 为终端设备
- 逻辑设备 1 为交采设备
- 对于单芯片电能表,只有一个逻辑设备 0
- 对于双芯片电能表
- 逻辑设备 0 为数据管理设备
- 逻辑设备 1 为计量设备
- 对于带交采的终端
- 预先建立的应用连接对象为逻辑设备必须具备的对象
- 应用连接对象为可选对象,根据访问权限所需进行增加
- 其他接口类对象为可选对象,根据设备功能所需进行增加
数据链路层
帧结构
采用异步式传输帧结构,帧格式如下:
| 传输帧格式 | 字节数 |
| --------- | ---- | ---- |
| 起始字符(68H) | |
| 长度域 L | 2 |
| 控制域 C | 1 |
| 地址域 A | 可变 |
| 帧头校验 HCS | 2 |
| 链路用户数据 | |
| 帧校验 FCS | 2 |
| 结束字符(16H) | |
长度域 L
长度域 L 由 2 字节组成,采用 BIN 编码。
用户数据长度由 bit 0 ~ bit 13 组成,是传输帧中除起始字符和结束字符之外的帧字节数。
控制域 C
控制域格式定义
控制域 C 为 1 个字节:
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
---|---|---|---|---|---|---|---|
传输方向位 DIR | 启动标志位 PRM | 分帧标志位 | 保留 | 扰码标志位 | 功能码 | 功能码 | 功能码 |
传输方向位及启动标志位
- 传输方向位:DIR=0 表示此帧是由客户机发出的;DIR=1 表示此帧是由服务器发出的
- 启动标志位:PRM=1 表示此帧是由客户机发起的;PRM=0 表示此帧是由服务器发起的
传输方向位 DIR 和启动标志位 PRM 组合意义:
DIR | PRM | 组合意义 |
---|---|---|
0 | 0 | 客户机对服务器上报的响应 |
0 | 1 | 客户机发起的请求 |
1 | 0 | 服务器发起的上报 |
1 | 1 | 服务器对客户机上报的响应 |
分帧标志位
- 分帧标志位为 1,表示此帧链路用户数据为 APDU 片段,收齐所有片段按片段序号合并后为完整 APDU
- 分帧标志位为 0,表示此帧链路用户数据为完整 APDU
扰码标志位
- 扰码标志位为 1,表示此帧链路用户数据为扰码编码格式,发送时链路用户数据按字节加 33H
- 扰码标志位为 0,表示此帧链路用户数据为默认编码格式,链路用户数据不加 33H
- 响应数据帧扰码编码格式应与请求/上报数据帧扰码编码格式一致
功能码
功能码采用 BIN 编码:
功能码 | 服务类型 | 应用说明 |
---|---|---|
0 | 保留 | |
1 | 链路管理 | 链路连接管理(登录,心跳,退出登录) |
2 | 保留 | |
3 | 用户数据 | 应用连接管理及数据交换服务 |
4~7 | 保留 |
地址域 A
地址域 A 由可变字节数的服务器地址 SA、和 1 字节的客户机地址 CA 组成。
服务器地址 SA
服务器地址定义
服务器地址由地址类型、逻辑地址、地址长度 N 及其 N 个字节地址组成。
服务器地址第一个字节:
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
---|---|---|---|---|---|---|---|
地址类型 | 地址类型 | 逻辑地址 | 逻辑地址 | 地址长度 N | 地址长度 N | 地址长度 N | 地址长度 N |
- bit0…bit3:为地址的字节数,取值范围:0~15,对应表示 1~16 个字节长度
- bit4…bit5:为逻辑地址
- bit6…bit7:为服务器地址的地址类型
- 0 表示单地址
- 1 表示通配地址
- 2 表示组地址
- 3 表示广播地址
单地址
当服务器地址 SA 的地址类型为单地址时,其地址长度为可变长度,字节数由地址长度域表示,最长 16 字节,对应取值范围为1…99999999999999999999999999999999,0 保留。
采用压缩 BCD 码的方式,即每字节二进制高低各 4 位分别编码表示两个 0 到 9 的十进制数,高位在前,低位在后:
- bit7…bit4 对应十进制高位
- bit3…bit0 对应十进制低位
当服务器地址的十进制位数为奇数时,最后字节中的十进制低位(即 bit3…bit0)为 FH 时,表示为无效。比如单地址 123456789 的排列:
第 1 字节 | 第 1 字节 | 第 2 字节 | 第 2 字节 | 第 3 字节 | 第 3 字节 | 第 4 字节 | 第 4 字节 | 第 5 字节 | 第 5 字节 |
---|---|---|---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | F |
通配地址
当服务器地址的地址类型为通配地址时,其地址长度为可变长度,编码方式同单地址。
通配符对应十进制按位使用,即通配地址的某些十进制位为 AH,表示该位可为 0 到 9 的任意值,同时,凡不大于传输帧中通配地址所能表示的最大值的,且符合通配地址要求的服务器地址被选中。
比如:通配地址=12345678A,表示服务器地址不大于 999999999 的且符合 123456780…123456789 的服务器都需响应。
第 1 字节 | 第 1 字节 | 第 2 字节 | 第 2 字节 | 第 3 字节 | 第 3 字节 | 第 4 字节 | 第 4 字节 | 第 5 字节 | 第 5 字节 |
---|---|---|---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | A | F |
组地址
当服务器地址 SA 的地址类型为组地址时,编码方式同单地址。组地址对系统中凡是属于该群组的服务器都有效,但都无需回答。
广播地址
当服务器地址 SA 的地址类型为广播地址时,广播地址=AAH。广播地址对系统所有服务器都有效,但都无需回答。
客户机地址 CA
客户机地址 CA 用 1 字节无符号整数表示,取值范围 0…255,值为 0 表示不关注客户机地址。
帧头校验 HCS
帧头校验 HCS 为 2 字节,是对帧头部分除起始字符和 HCS 本身之外的所有字节的校验。
链路用户数据
链路用户数据包含一个完整的应用层协议数据单元(APDU)字节序列或 APDU 的分帧片段。
帧校验 FCS
帧校验 FCS 为 2 字节,是对整帧除起始字符、结束字符和 FCS 本身之外的所有字节的校验。
字节格式
帧的基本单元为 8 位字节。链路层传输顺序为低位在前,高位在后;低字节在前,高字节在后。
传输规则
字节规则
传输规则包括:
- 采用串行通信方式实现本地数据传输时,在发送数据时,在有效数据帧前加 4 个 FEH 作为前导码
- 线路空闲状态为二进制 1
- 帧的字符之间无线路空闲间隔;两帧之间的线路空闲间隔最少需 33 位
- 如帧头校验 HCS 和帧校验 FCS 检出了差错,两帧之间的线路空闲间隔最少需 33 位
- 接收方校验:
- 对于每个字符:校验起动位、停止位、偶校验位
- 对于每帧:
- 检验帧头中的起始字符和帧头校验 HCS
- 识别长度 L
- 每帧接收的字符数为长度域 L+2
- 帧校验 FCS
- 结束字符
- 校验出一个差错时,线路空闲间隔(帧的字符之间无线路空闲间隔;两帧之间的线路空闲间隔最少需 33 位)
- 若这些校验有一个失败,舍弃此帧;若无差错,则此帧数据有效
分帧规则
分帧规则概述
当一个完整的应用层协议数据单元长度超过发送帧最大尺寸时,可采用分帧传输。分帧数据接收端应对分帧传输进行逐条确认。采用分帧传输时,控制域中分帧标志位置 1。
分帧传输格式定义
分帧传输时,链路层的链路用户数据为分帧传输帧。分帧传输帧格式定义如下:
分帧格式域 |
---|
APDU 片段 |
APDU 片段 |
…… |
APDU 片段 |
分帧传输的确认帧仅包含分帧格式域,不含 APDU 片段
分帧格式域定义
分帧格式域为 2 字节,按位或位的组合使用。
- bit0…bit11:表示分帧传输过程的帧序号,取值范围 0…4095,循环使用
- bit12…bit13:保留
- bit15=0,bit14=0:表示分帧传输数据起始帧
- bit15=1,bit14=0:表示分帧传输确认帧(确认帧不包含 APDU 片段域)
- bit15=0,bit14=1:表示分帧传输最后帧
- bit15=1,bit14=1:表示分帧传输中间帧
分帧传输交换规则
分帧数据交换,可用于服务器或客户机任意一侧,可用于主动发起的数据服务或者被动应答的数据服务,分帧传输的数据内容,不可自解析,必须收齐所有数据块,组合后,才可得到完整的一个 APDU 应用数据单元。
由服务器或客户机启动传输的数据分帧传输时序如下:
服务器响应客户机请求的数据分帧传输时序如下:
分帧传输格式域包含分帧序号(block)、分帧类型(type)。
- 分帧的第一帧数据,block=0,type=0
- 分帧的最后一帧,block=N(N为实际包序号),type=1,分帧传输完毕
- 分帧传输确认,type=2,block 为最近一次收到正确的帧序号
- 对方在接收到该确认报文后应准备并传输下一个数据块,此数据块包含分帧序号 block=上次正确发送的帧序号 +1,这样数据块的交换和确认应正常继续下去,直到发送完最后一个数据块,在接收到最后一个数据块后,分帧传输过程完成。
应用层
应用层服务规范
应用层服务概述
应用层服务对象组件
应用层服务对象是构成客户机和服务器应用层的主要组件,它使用数据链路层提供的服务,服务规范包含客户机和服务器应用进程在各自应用层的逻辑接口,并向应用进程提供服务。客户机和服务器的应用服务对象都包括预连接、应用连接和数据交换三个必备组件。
预连接
预连接服务适用于交换网络传输信道,如以太网、GPRS 等,当其完成物理连接,建立透明通道后,需要在此通道上建立预连接并进行管理。
预连接对应客户机和服务器各自应用层提供的服务如下:
- 客户机应用层服务:LINKLINKLINKLINK(.indication,.response)
- 服务器应用层服务:LINKLINKLINKLINK(.request,.confirm)
预连接服务(LINK)由服务器发起,客户机响应,其包括:
登录:在完成物理连接,建立透明通道后,服务器应用进程按预连接配置参数向指定客户机发出登录请求,客户机应用进程给予确认,完成预连接
心跳:服务器采用“心跳”的方式来保证预连接通道处于活动状态
退出登录:在建立预连接后,不允许服务器主动断开。若要变更,需重新配置服务器预连接参数,服务器在重启后生效;或接收到客户机执行“复位”方法后,向原客户机发出退出登录指示,然后再按照新配参数执行新的预连接登录。
对于本地通信信道,如 RS485、红外等,当物理连接建立时,默认预连接的通道即存在,不需要额外的建立以及预连接管理。
应用连接
应用连接窗口
为访问服务器的接口类对象,首先要建立一个应用连接,并创建一个可以相互通信的语境。这个语境主要包含:应用语境的信息、使用身份验证机制的信息,以及其他需要的信息,这些信息包含在“应用连接”的接口类对象中。
服务器可以授予不同的访问权限给应用连接,访问权限涉及一组接口类对象,这组对象可以在给定的应用连接内被访问,即可视对象。
客户机可以通过读取应用连接对象的“可访问对象列表”属性而获得可视对象列表,即应用连接窗口,并利用应用连接对象所提供的方法,在已建立的应用连接内获得当前语境等更多的信息。
在预连接通道上,默认具有一个最低权限级别的应用连接窗口,即“预建立的应用连接窗口”,在此窗口内,客户机不需要进行应用连接协商以及安全认证等便可访问该应用连接窗口的内容。
建立和断开应用连接
建立应用连接(CONNECT),由客户机向服务器发起,用于确认客户机和服务器双方通信的应用语境,包含协议一致性、功能一致性以及安全认证等内容。
服务器可同时支持若干个应用连接,互不干扰,但对同一个客户机,同时仅支持一个应用连接,当同一个客户机再次请求建立应用连接时,服务器如接受了客户机的再次请求,则前一个应用连接自动失效。
断开应用连接(RELEASE)用于正常断开一个已经建立的应用连接。由于不允许服务器提出正常断开应用连接的请求,所以 RELEASE.request 服务只能由客户机提出,并且通常情况下,服务器不得拒绝此请求。
每一个应用连接在建立过程中,可以协商应用连接的静态超时时间,当连续无通信时间达到静态超时时间后,服务器将使用 RELEASE.notification 通知客户机,应用连接失效将被断开,此服务不需要客户机做任何响应。
应用连接对应客户机和服务器各自应用层提供的服务见下表:
服务名称 | 客户机应用层服务 | 服务器应用层服务 |
---|---|---|
客户机建立应用连接 | CONNECT(.request,.confirm) | CONNECT(.indication,.response) |
客户机断开应用连接 | RELEASE(.request,.confirm) | RELEASE(.indication,.response) |
超时断开应用连接 | RELEASE(.notification) |
注:indication [ˌɪndɪˈkeɪʃn] n. 指示;象征;表明;标示
预连接时建立的应用连接
预连接时建立的应用连接不需要使用 CONNECT 服务,即认为 CONNECT 已经完成,因此,预连接时建立的应用连接可以看成是在客户机和服务器之间完成预连接时应用连接已经存在,任何时候它都不能被断开,仅具有最低权限级别,窗口内容由服务器定义。
这种应用连接简化了客户机和服务器之间数据交换,省掉了建立和断开应用连接阶段,仅有数据交换阶段。当客户机需要得到较高权限的服务器服务时,客户机必须发起建立较高权限的应用连接。
数据交换
数据交换服务是用于客户机和服务器之间的数据交换,是通过逻辑名引用来访问接口对象的属性或方法。数据通信服务对应客户机和服务器各自应用层提供的服务见下表。
服务名称 | 客户机应用层服务 | 服务器应用层服务 |
---|---|---|
读取 | GET(.request,.confirm) | GET(.indication,.response) |
设置 | SET(.request,.confirm) | SET(.indication,.response) |
操作 | ACTION(.request,.confirm) | ACTION(.indication,.response) |
上报 | REPORT(.indication,.response) | REPORT(.notification,.confirm) |
代理 | PROXY(.request,.confirm) | PROXY(.indication,.response) |
这些服务可分为两种通信类型:请求/响应类型、通知/确认类型:
- 请求/响应类数据交换服务是:读取(GET)、设置(SET)、操作(ACTION)、代理(PROXY)
- 通知/确认类数据交换服务是:上报(REPORT)
请求/响应类数据交换服务是通过客户机和服务器应用进程之间的数据交换来提供并完成的,即:客户机应用进程通过调用应用层的某个服务请求 XX.request,服务器应用层接收到客户机请求后向服务器应用进程发出服务指示 XX.indication,然后应用进程通过调用服务 XX.response 以响应客户机请求,客户机应用层接收到服务器响应后向客户机应用进程返回服务确认 XX.confirm。其服务顺序见下图。
对于请求/响应类数据通信服务,在通信语境商定后,客户机和服务器的数据通信服务集是完全对等互补的,即:服务集相同,只是 XX.request 服务换成了 XX.indication 服务,XX.response 服务换成了 XX.confirm 服务。因此:
- 一个 XX.request 的 APDU 与一个 XX.indication 的 APDU 对等
- 一个 XX.response 的 APDU 与一个 XX.confirm 的 APDU 对等
通知/确认类数据交换服务也是通过客户机和服务器应用进程之间的数据交换来提供并完成的,即:在客户机向服务器定制了主动上报的情况下,服务器应用进程通过调用应用层服务 YY. notification,客户机应用层接收到服务器上报后向客户机应用进程发出服务指示 YY.indication,然后客户机应用进程通过调用服务 YY.response 向服务器予以确认响应,服务器应用层接收到客户机确认响应后向服务器应用进程返回服务确认 YY.confirm。其服务顺序见下图。
对于通知/确认类数据通信服务,在通信语境商定后,客户机和服务器的数据通信服务集也是完全对等互补的,即:服务集相同,只是 YY.notification 服务换成了 YY.indication 服务,YY.response 服务换成了 YY.confirm 服务。因此:
- 一个 YY. notification 的 APDU 与一个 YY.indication 的 APDU 对等
- 一个 YY.response 的 APDU 与一个 YY.confirm 的 APDU 对等
有关传输的时间标签
时间标签用于传输的时序和时效性判断,其包括一个开始发送时间和一个允许传输延时时间。
允许传输延时时间,是指从开始发送至对方接收到能解析的完整的应用层数据单元之间所允许的传输延时时间。
对于请求/响应类数据交换服务,时间标签由客户机产生,随请求传送给服务器,服务器据此判决收到的请求的时序和时效性,如判别有效,响应收到的请求,并在响应中将接收到的时间标签返回客户机。
对于通知/确认类数据通信服务,时间标签由服务器产生,随通知传送给客户机,客户机据此判决收到的通知的时序和时效性,如判别有效,确认收到的通知,并在确认中将接收到的时间标签返回服务器。
时效性判断规则:在时间标签中允许传输延时时间大于零的前提下,如果接收方的当前时间与时间标签中的开始发送时间之间的时差大于时间标签中的允许传输延时时间,则放弃处理;反之,则处理。
有关服务器信息上报
服务器上报服务
服务器上报服务(REPORT)是通过“注册-通知-撤销注册”的机制给客户机提供的一种系统级服务。客户机可通过 GET 服务查询出服务器支持的可注册后上报的服务集(如事件或定时数据上报等),并可根据系统需求通过 SET 服务以自定义形式注册部分或全部服务。注册成功后,服务器在检测到上报条件满足时(如产生了事件或定时上报时间到等),通过 REPORT.notification 服务及时通知客户机。
该服务默认对远程通道有效,本地通道提供同样服务应由服务器界面提供相关信息指示,并经配置后使用。
服务器 APDU 的跟随上报信息域
服务器应用层协议数据单元(APDU)中的可选的跟随上报信息域,是当系统不适合或服务器不支持上报服务(REPORT)时,用于作为 ACD 标志事件上报方式的补充,以实现更及时上报客户机注册的上报信息。
该域同样默认对远程通道选择性有效,本地通道提供同样服务应由服务器界面提供相关信息指示,并经配置后使用。
预连接
LINK.request 服务
本服务由服务器应用进程调用,用于向远方客户机应用进程提出登录、心跳或退出登录三类预连接请求。用原语 LINK.request 表示,其服务语义和参数说明如下。
- 请求类型 —— 登录、心跳退出
- 心跳周期 —— 两次心跳请求的时间隔
- 请求时间 —— 请求时服务器的时钟时间
LINK.indication 服务
本服务由客户机应用层调用,用于向客户机应用进程指示接收到远方服务器提出的预连接请求。用原语 LINK.indication 表示,服务参数同 LINK.request。
LINK.response 服务
本服务由客户机应用进程调用,用于向服务器应用进程响应预连接请求。用原语 LINK.response 表示,其服务语义和参数说明如下:
- 请求类型 —— 登录、心跳、退出登录
- 结果 —— 用于表明请求是否成功或失败及其原因
- 请求时间 —— 即为 LINK.request 的“请求时间”
- 收到时间 —— 为接收到 LINK.indication 的时间
- 响应时间 —— 为发出 LINK.response 的时间
- 时间可信度 —— 用于表明客户机时钟的准确性
LINK.confirm 服务
本服务由服务器应用层调用,用于向服务器应用进程指示接收到预连接请求的响应。用原语 LINK.confirm 表示,服务参数同LINK.response。
建立应用连接
CONNECT.request 服务
本服务由客户机应用进程调用,用于向远方服务器的应用进程提出建立应用连接请求。用原语 CONNECT.request 表示,其服务语义和参数说明如下:
服务语义:
- 期望的应用层协议版本号
- 期望的协议一致性块
- 期望的功能一致性块
- 客户机发送帧最大尺寸
- 客户机接收帧最大尺寸
- 客户机接收帧最大窗口尺寸
- 客户机最大可处理 APDU 尺寸
- 期望的应用连接超时间
- 认证机制信息
- 公共连接 —— 不需要安全机制
- 一般密码 —— 使用明文密码
- 对称加密 —— 使用 ESAM 对称加密进行安全认证,并建立会话密钥
- 数字签名 —— 使用 ESAM 非对称加密进行安全认证,并建立会话密钥
CONNECT.indication 服务
本服务由服务器应用层调用,用于向服务器应用进程指示接收到远方客户机提出的建立应用连接的请求。用原语 CONNECT.indication 表示,服务参数同 CONNECT.request。
CONNECT.response 服务
本服务由服务器应用进程调用,用于向客户机应用进程返回请求结果。用原语 CONNECT.response 表示:
服务原语:
- 服务器厂商版本信息
- 商定的应用层协议版本号
- 商定的协议一致性块
- 商定的功能一致性块
- 服务器发送帧最大尺寸
- 服务器接收帧最大尺寸
- 服务器接收帧最大窗口尺寸
- 服务器最大可处理 APDU 尺寸
- 商定的应用连接超时间(单位:秒)
- 认证响应
CONNECT.confirm 服务
本服务由客户机应用层调用,用于向客户机应用进程指示接收到建立应用连接请求的响应。用原语 CONNECT.confirm 表示,服务参数同 CONNECT.response。
断开应用连接
RELEASE.request 服务
本服务由客户机应用进程调用,用于向远方服务器的应用进程提出断开应用连接请求。用原语 RELEASE.request 表示。
RELEASE.indication 服务
本服务由服务器应用层调用,用于向服务器应用进程指示接收到远方客户机提出的断开应用连接的请求。用原语 RELEASE.indication 表示,服务参数同RELEASE.request。
RELEASE.response 服务
本服务由服务器应用进程调用,用于向客户机应用进程返回请求结果。用原语 RELEASE.response 表示,其服务语义和参数说明如下:
- 结果:请求的结果,通常情况下,服务器不得拒绝此请求
RELEASE.confirm 服务
本服务由客户机应用层调用,用于向客户机应用进程指示接收到断开应用连接请求的响应。用原语 RELEASE.confirm 表示,服务参数同 RELEASE.response。
RELEASE.notification 服务
本服务由服务器应用进程调用,用于通知客户机应用进程连接因超时而失效将被断开,此服务不需要客户机做任何响应。用原语 RELEASE.notification 表示,其服务语义及其参数说明如下:
- 应用连接建立时间:建立应用链接时的终端时间
- 服务器当前时间:发出连接断开的终端时间
读取
GET.request 服务
本服务由客户机应用进程调用,用于向远方服务器的应用进程请求服务器的若干个接口类对象的所有属性值。用原语 GET.request 表示,其服务语义和参数说明如下:
服务原语:
GET.request
(
请求类型,
对象属性描述符,
{对象属性描述符, }
数据块序号
)
参数说明:
-
请求类型:用于区分不同的读取请求,为以下几种类型
- 读取一个对象属性
- 读取若干个对象属性
- 读取一个记录型对象属性
- 读取若干个记录型对象属性
- 读取分帧响应的下一个数据块,仅在被请求的数据响应不能在一个 GET.response APDU 中传输时才使用
-
对象属性描述符
- 仅当“请求类型”为 仅当“请求类型”为第 1 种至第 4 种时才出现
- 用于表明要读取的对象属性,分为一般型和记录型两种
-
数据块序号
- 用于表明正确接收到的最近一次数据块序号,仅当“请求类型” 为第 5 种是才出现
GET.indication 服务
本服务由服务器应用层调用,用于向服务器应用进程指示接收到远方客户机 GET.request 服务请求。用原语 GET.indication 表示,服务参数同 GET.request。
GET.response 服务
本服务由服务器应用进程调用,用于对应 GET.indication 向客户机应用进程返回请求结果。用原语 GET.response 表示,其服务语义和参数说明如下:
服务原语:
GET.GET.GET.GET. response (响应类型,读取结果,{读取结果,}数据块序号)
参数说明:
-
响应类型:用于表明响应是否包含对应 GET.request 服务调用的响应,或只包含服务调用的部分响应,对应请求类型,响应类型分为以下几种类型
- 读取一个对象属性的响应
- 读取若干个对象属性的响应
- 读取一个记录型对象属性的响应
- 读取若干个记录型对象属性的响应
- 分帧响应一个数据块,分帧方式按请求对象属性分成能自解释的若干独立响应,且这一类根据 GET.request 请求类型还分为一般、记录两种对象属性。
-
读取结果
- 用于表明读取请求的响应结果,包括对象属性描述符及其数值
- 对象属性为一般型、记录型两种
- 如“读取结果”的编码形式不适合在一个 APDU 中传输,则它应采用分帧响应,即“响应类型”为第 5 种
-
数据块序号
- 用于表明本 APDU 中数据块的序号
- 仅在“响应类型”为第 5 种时出现
GET.confirm 服务
本服务由客户机应用层调用,用于向客户机应用进程指示接收到服务器 GET.response APDU。用原语 GET.confirm 表示,服务参数同 GET.response。
设置
SET.request 服务
本服务由客户机应用进程调用,用于向远方服务器的应用进程设置服务器的若干个接口类对象的一个或所有的属性值。用原语 SET.request 表示,其服务语义和参数说明如下:
服务原语:
SET.request (请求类型,对象属性描述符及其数值,{对象属性描述符及其数值, }对象属性描述符,{对象属性描述符, })
参数说明:
-
请求类型:用于区分不同的设置请求,分为以下几种类型
- 设置一个对象属性请求
- 设置若干个对象属性请求
- 设置后读取若干个对象属性请求
对象属性描述符及其数值:用于表明要设置的对象属性及其数值
对象属性描述符:仅当“请求类型”为第 3 种时才出现,用于表明在设置后要读取的对象属性,对象属性仅为一般型
SET.indication 服务
本服务由服务器应用层调用,用于向服务器应用进程指示接收到远方客户机 SET.request 服务请求。用原语 SET.indication 表示,服务参数同SET.request。
SET.response 服务
本服务由服务器应用进程调用,用于对应 SET.indication 向客户机应用进程返回请求结果。用原语SET.response表示,其服务语义和参数说明如下:
服务原语:
SET.response(响应类型,设置结果,{设置结果, }读取结果,{读取结 果, })
参数说明:
-
响应类型:用于表明响应所对的 SET.request 服务的请求类型,对应请求类型,响应类型分为以下几种
- 设置一个对象属性的确认信息
- 设置若干个对象属性的确认信息
- 设置若干个对象属性的确认信息以及读取若干个对象属性的响应
设置结果:用于表明设置的执行结果,包括对象属性描述符及其结果
读取结果:仅在“响应类型”为第 3 种时出现,用于表明设置后读取属性的响应结果,包括设置后读取的对象属性描述符及其数据,对象属性仅为一般型
SET.confirm 服务
本服务由客户机应用层调用,用于向客户机应用进程指示接收到服务器 SET.response APDU。用原语 SET.confirm 表示,服务参数同 SET.response。
操作
ACTION.request 服务
本服务由客户机应用进程调用,用于调用远方服务器应用进程中的若干个接口类对象的若干个方法。用原语 ACTION.request 表示,其服务语义和参数说明如下:
服务原语:
ACTION.request(请求类型,对象方法描述符及参数,{对象方法描述符及参数, }对象属性描述符,{对象属性描述符, })
参数说明:
-
请求类型:用于区分不同的操作请求,为以下几种类型
- 操作一个对象方法请求
- 操作若干个对象方法请求
- 操作若干个对象方法后读取若干个对象属性请求
对象方法描述符:用于表明要操作的对象方法
对象属性描述符:仅当“请求类型”为第 3 种时才出现,用于表明操作执行后要读取的对象属性,对象属性仅为一般型
ACTION.indication 服务
本服务由服务器应用层调用,用于向服务器应用进程指示接收到远方客户机 ACTION.request 服务请求。用原语 ACTION.indication 表示,服务参数同 ACTION.request。
ACTION.response 服务
本服务由服务器应用进程调用,用于对应 ACTION.indication 向客户机应用进程返回请求结果。用原语 ACTION.response表示,其服务语义和参数说明如下:
服务原语:
ACTION.response (响应类型,操作结果,{操作结果, }读取结果,{读取结果, })
参数说明:
-
响应类型:用于表明响应所对应的 ACTION.request 服务的请求类型,对应请求类型,响应类型分为以下几种类型
- 操作一个对象方法响应
- 操作若干个对象方法响应
- 操作若干个对象方法后读取若干个对象属性的响应
操作结果:用于表明调对象方法的执行结果,包括对象方法描述符及其结果
读取结果:仅在“响应类型”为第 3 种时出现,用于表明操作执行后要读取的对象属性的响应结果,包括对象属性描述符及其数据,对象属性仅为一般型
ACTION.confirm 服务
本服务由客户机应用层调用,用于向客户机应用进程指示接收到服务器 ACTION.response APDU。用原语 ACTION.confirm 表示,服务参数同 ACTION.response。
上报
REPORT.notification 服务
本服务由服务器应用进程调用,用于向远方客户机应用进程上报信息,该信息是由客户机通过注册方式预定的。用原语 REPORT.notification 表示,其服务语义和参数说明如下:
服务原语:
REPORT.notificationR(通知类型,对象属性描述符及其数值,{对象属性描述符及其数值, })
参数说明:
-
通知类型:用于区分不同的上报通知,为以下几种类型
- 上报若干个对象属性
- 上报若干个记录型对象属性
对象属性描述符及其数值:用于表明上报的信息
REPORT.indication 服务
本服务由客户机应用层调用,用于向客户机应用进程指示接收到远方服务器 REPORT.notification 服务通知。用原语 REPORT.indication 表示,服务参数同 REPORT.notification。
REPORT.response 服务
本服务由客户机应用进程调用,用于对应 REPORT.indication 向服务器应用进程返回确认结果。用原语 REPORT.response 表示,其服务语义和参数说明如下:
服务原语:
REPORT.response(响应类型,确认结果,{确认结果, })
参数说明:
-
响应类型:用于表明响应所对的 REPORT.indication 服务的通知类型,对应通知类型,响应类型分为以下几种
- 上报若干个对象属性的响应
- 上报若干个记录型对象属性的响应
确认结果:用于表明上报的确认结果,为被确认的对象属性描述符,对象属性为一般型和记录型 2 种
REPORT.confirm 服务
本服务由服务器应用层调用,用于向服务器应用进程指示接收到客户机 REPORT.response APDU。用原语 REPORT.confirm表示,服务参数同REPORT.response。
代理
PROXY.request 服务
本服务由客户机应用进程调用,用于向远方服务器(代理服务器)的应用进程提出代理请求。用原语 PROXY.request 表示,其服务语义和参数说明如下:
服务原语:
PROXY.request(请求类型,目标服务器地址 /端口,{目标服务器地址, }对象属性描述符,{对象属性描述符, }对象属性描述符及其数值,{对象属性描述符及其数值, }对象方法描述符,{对象方法描述符, }代理相关参数,{代理相关参数, }{透明命令,})
参数说明:
-
请求类型:用于区分不同的代理请求,为以下几种类型
- 代理读取若干个服务器的若干个对象属性
- 代理读取一个服务器的记录型对象属性
- 代理设置若干个服务器的若干个对象属性
- 代理设置后读取若干个服务器的若干个对象属性
- 代理操作若干个服务器的若干个对象方法
- 代理操作后读取若干个服务器的若干个对象方法和属性
- 代理透明转发命令
目标服务器地址:用于表明代理的目标服务器地址,如 PROXY.request 的目标服务器地址采用了通配地址,响应时要分解为确定的服务器单地址,即 PROXY.response 的目标服务器地址皆为单地址
-
对象属性描述符:用于表明要代理读取的对象属性
- 当“请求类型”为 1、4、6 时,对象属性仅为一般型
- 当“请求类型”为 2 时,对象属性为记录型
对象属性描述符及其数值:用于表明要代理设置的对象属性,仅当“请求类型” 为3、4 时才出现,对象属性仅为一般型
对象方法描述符:用于表明要代理操作的对象方法,仅当“请求类型”为5、6 时才出现
代理相关参数:与代理请求相关的所需参数
PROXY.indication 服务
本服务由服务器应用层调用,用于向服务器应用进程指示接收到远方客户机 PROXY.request 服务请求。用原语 PROXY.indication 表示,服务参数同 PROXY.request。
PROXY.response 服务
本服务由服务器应用进程调用,用于对应 PROXY.indication 向客户机应用进程返回代理请求的代理执行结果。用原语 PROXY.response 表示,其服务语义和参数说明如下:
服务原语:
PROXY.response (响应类型,目标服务器地址/端口 ,{目标服务器地址, }读取结果,{读取结果, }设置结果,{设置结果 ,}操作结果,{操作结果, })
参数说明:
-
响应类型:用于表明响应所对的 PROXY.request 服务的请求类型,对应请求类型,响应类型分为以下几种类型
- 1 代理读取若干个服务器的若干个对象属性的响应
- 2 代理读取一个服务器的一个记录型对象属性的响应
- 3 代理设置若干个服务器的若干个对象属性的确认
- 4 代理设置后读取若干个服务器的若干个对象属性的确认和响应
- 5 代理操作若干个服务器的若干个对象方法的确认
- 6 代理操作后读取若干个服务器的若干个对象方法和属性的确认和响应
- 7 代理透明转发命令的响应
目标服务器地址:用于表明代理的目标服务器地址
读取结果:当“响应类型”为 1、2、4、6 时才出现,用于表明代理读取请求的响应结果,包括对象属性描述符及其数值,对象属性对应请求类型为一般型或记录型 2 种
设置结果:仅当“响应类型”为 3、4 时才出现,用于表明代理设置的执行结果,包括设置的对象属性描述符及其结果,对象属性仅为一般型
操作结果:仅在“响应类型”为 5、6 时出现,用于表明代理操作对象方法的执行结果,包括对象方法描述符及其操作结果
PROXY.confirm 服务
本服务由客户机应用层调用,用于向客户机应用进程指示接收到服务器 PROXY.response APDU。用原语 PROXY.confirm 表示,服务参数同 PROXY.response。
应用层协议规范
建立/断开应用连接的协议
建立应用连接
建立应用连接是本标准的关键组件,建立应用连接借助于 CONNECT.request /.indication/.response /.confirm 服务。
客户机应用进程应首先调用 CONNECT.request 请求服务,调用该服务前,本标准所需的预链接已经建立。基于预链接的低层连接,客户机应构造一个 CONNECT-Request APDU。该 CONNECT-Request APDU 是发送给服务器应用层的第一个报文。
服务器应用层从接收到的 CONNECT-Request APDU 中提取出来的适当参数调用 CONNECT.indication 服务原语向服务器应用进程发出指示。
服务器应用进程分析接收到的 CONNECT.indication 原语,并且决定是否接受提出的应用连接请求,通过核实之后,服务器应用进程应调用 CONNECT.response 服务原语,表明接受或不接受提出的连接请求。
如果成功的话,服务器应构造相应的 CONNECT-Response APDU,并通过现有的预链接通道发送给远方客户机应用层。从这一时刻起,服务器能够在该连接内接收数据通信服务请求,发送相应的响应。至此,应用连接建立完毕,服务器进入数据通信阶段。
如果服务器不能接受连接请求,服务器应用层应构造 CONNECT-Response APDU,其中包含拒绝连接的状态以及原因,发送至远方客户机应用层。
在客户机侧,提取接收到的 CONNECT-Response APDU 中的参数,并通过 CONNECT.confirm 服务原语发送给客户机应用进程,如连接请求被接受,从这时刻起,在协商应用的语境中,应用连接建立完成。
断开应用连接
概述
现有应用连接能够被正常断开或超时被断开,正常断开由客户机应用进程启动,通知服务器侧,请求断开当前应用连接。
超时被断开意味着连接被异常终止,当应用层连续无通信时长超过语境约定的超时时间,应用连接将被断开,此服务只能由服务器应用进程启动。
正常断开应用连接
正常断开应用连接总是由客户机应用通过调用 RELEASE.request 的服务启动。根据协议生成一个 RELEASE-Request APDU,通过低层支持协议发送到服务器侧。
服务器应用层把接收到的 RELEASE-Request 解释为应用连接的断开请求,并且通过 RELEASE.indication 服务原语向服务器应用进程指示该请求。
服务器应用进程应接受断开请求并调用 RELEASE.response 服务(通常,服务器不能拒绝客户机的断开连接请求)。
通信超时导致应用连接被断开
本标准约定了一种情景,当应用连接建立后(不包括预建立时建立的应用连接),如果连续无数据传输服务时长(不包括预链接管理服务)达到会话语境约定的超时时间后(造成通信超时的原因涵盖包括物理层故障在内的任何原因),服务器应用进程将调用 RELEASE.notification 服务,通知客户机此连接将被断开,客户机不需要做任何响应。
请求/响应数据交换的协议
短帧的数据交换
短帧,在此特指完整的一帧 APDU 长度不超过会话语境约定的发送或接收数据长度;长帧,在此特指一帧 APDU 长度超过会话语境约定的发送或接收数据长度,需要采取分帧传输。
- 读取(.request/.indication/.response/.confirm)
- 设置(.request/.indication/.response/.confirm)
- 操作(.request/.indication/.response/.confirm)
- 代理(.request/.indication/.response/.confirm)
读取和设置服务用于引用接口对象实例的属性,操作服务用于引用接口对象的一个方法,代理服务用于引用远方服务器的对象属性或方法。上述服务,在采用短帧数据交换时,具有相同的时序,在此一并描述。
服务器的应用进程一旦接收到数据通信服务指示,应检查该服务能否被提供(检查合法性、可行性等),如果一切都正确,服务器应用进程应在本地使用相应的具体对象提供所请求的服务。服务器应用层应生成一个适当的 .response 报文,包含 .request 的执行结果,发送到客户机侧,一个交互流程完成。
长帧的数据交换
长帧传输的读取服务
读取服务的分帧传输规范仅适用于 GET.response 服务原语中的数据。
在 GET.response 服务中多重属性引用时,其服务参数编码形式的长度不能超过发送帧最大尺寸。如果 GET.response 服务参数编码长度超过最大尺寸时,请使用分帧服务进行传输。
服务器一旦接收到一个 GET.request,服务器应用进程就应组装所请求的数据,如果这些数据能够放在一个 APDU 中,服务器应用进程应调用对应短帧类型的 Get.response 服务,其结果参数包含所请求属性的值。
如果数据长度超过发送帧最大尺寸,则应使用分帧传输,分帧传输有两种可选模式,一种单帧可自解析模式,一种为不可自解析模式,不可自解析传输模式必须所有数据片段接收完毕后,才能正确解析相应的数据。单帧可自解析的分帧方式,每一帧中必须包含完整的属性数据单元。
仅 GET.response 服务支持单帧可自解析模式,此章节时序图描述的为单帧自解析模式的时序,数据块传输模式,见「分帧规则」章节。
分帧响应 GetResponseNext 的 APDU 数据域,有两个关键的数据字段,分帧序号(block)、末帧标记(lastblock)。
- 分帧的第一帧数据,block(long-unsigned)=0,lastblock(BOOLEAN)= False
- 分帧的最后一帧,block=N(N 为实际包序号),lastblock=True,分帧传输完毕
注:Boolean ['bʊlɪən] 布尔值
客户机一旦接收到该 GetResponseNext,客户机应用进程知道所请求的响应数据已经超过接收帧最大尺寸,并准备处理后续帧传输,它应保存所接收的 APDU 的数据内容,并调用 GetRequestNext 服务对所接收到的数据块进行确认。
服务器在接收到该确认报文后应准备并传输下一个数据块,此数据块包含分帧序号 block=1,这样数据块的交换和确认应正常继续下去,直到发送完最后一个数据块,此时 response 的 lastblock (BOOLEAN) 参数应置为 True,并且客户机不对该数据块进行确认,在接收到最后一个数据块后,GET 服务的分帧传输过程完成。
如果分帧传输期间发生以下差错,传输过程将终止。差错情况如下:
服务器出于任何原因不能提供下一个数据块。这种情况下,服务器应发送一个 GetResponseNext 的 APDU,将 lastblock 参数置为 True,block 置为客户机所期望的值(接收到的 block+1),数据域 Result 参数包含一个 DAR 参数,用来指明差错原因。
服务器接收到 GetRequestNext 类型的 GET.indication,block 参数的值与服务器上一次发送的 block 参数值不相等。服务器对这种情况的解释为客户机期望终止正在进行的传输,服务器不再发送下一个数据块给客户机,而是返送一个 GetResponseNext APDU,将 lastblock 参数置为 True,block 为接收到的 block 参数值,数据域参数为 DAR=分帧传输已取消。
服务器在没有进行分帧传输时接收到 GetRequestNext 类型的 GET.indication。在这种情况下,使用 GetResponseNext APDU 进行响应。将 lastblock 参数置为 True,block 为接收到的 block 参数值,数据域参数为 DAR=不处于分帧传输状态。
在分帧传输期间,所有 APDU 中的 Invoke-Id 和 Priority 参数的值相同。如果在分帧传输期间,接收到其它服务请求,则按照优先级原则进行服务。
长帧传输的其它服务
本标准仅 GET.response 服务支持单帧可自解析模式,其他类型服务,数据域长度超过发送帧最大尺寸,需要采用分帧传输时,应使用分帧服务进行,分帧服务传输时序参见「分帧规则」章节。
上报/确认数据交换的协议
上报/确认类服务,在本标准用于服务器主动发起,传送事件或者其它定时任务数据到客户机,在 REPORT.request 服务中,其服务参数编码形式的长度不能超过发送帧最大尺寸。如果数据长度超出,请使用分帧服务进行传送。
客户在收到 REPORT.indication 指示时, 应使用 REPORT.response 进行确认, 在服务器收到 REPORT.confirm 时,方可认为主动上报发送成功,如果在约定的超时时间内,未收到确认,将再次发起 REPORT.request,APDU 中的 Invoke-Id 和 Priority 参数的值保持不变,在达到约定的最多重复次数后,如仍未收到确认帧,则放弃该 APDU 的主动上报。
上报/确认类服务,可以在服务器侧任意通信端口发起(包括本地端口以及远程端口,根据配置决定),确认状态与上报的通信端口相关。只有在端口预链接正确建立的前提下,服务器方可发起主动上报。
上一篇: IEEE 电力线通信标准开发流程
下一篇: 电力协议》第 376.1 号协议
推荐阅读
-
面向对象的用电信息数据交换协议
-
41 个下载免费 3D 模型的最佳网站-使用说明:使用权限可能因型号而异。因此,在下载文件之前,请仔细检查每个下载页面上的许可证和使用权限。 17. Clara.io Clara.io 是一个创建 3D 内容的全球平台,也是一个培养新 3D 艺术家的社区。Clara.io 提供+100,000个免费的3D模型,包括OBJ,Blend,STL,FBX,DAE,Babylon.JS,Three.JS格式,用于 Clara.io,Unity 3D,Blender,Sketchup,Cinema 4D,3DS Max和Maya。 使用说明:免费,标准和专业帐户仅供个人使用,如果您需要将 clara.io 用于商业用途,请与销售团队联系。 18. 3DExport 3DExport是一个市场,您可以在其中购买和销售用于CG项目的3D模型,3D打印模型和纹理。它提供15 +不同的3D格式供下载,如3DS MAX(.max),Cinema4D(.c4d),Maya(.mb,.ma),Lightwave(.lwo),Softimage(.xsi),Wavefront OBJ(.obj),Autodesk FBX(.fbx)等。它还提供15种不同的语言! 使用说明:免费下载仅供个人和非商业用途。 19. 3D Warehouse 3D Warehouse是一个开放的库,允许用户共享和下载SketchUp 3D模型,用于建筑,设计,施工和娱乐!任何人都可以免费制作,修改和重新上传内容到3D仓库,您可以找到任何您能想到的东西,如家具,电子产品,室内产品等。 使用说明:3D Warehouse中的所有模型都是免费的,因此任何人都可以下载文件以用于SketchUp甚至其他软件,如AutoCAD,Revit和ArchiCAD。 20. CadNav.com CadNav是CGI平面设计师和CAD / CAM / CAE工程师的在线3D模型库,我们提供超过50000 +免费3D模型和CAD模型下载。在CadNav网站上,您可以下载高质量的多边形网格3D模型,3D CAD实体对象,纹理,Vray材料,3D作品,CAD图纸等。 使用说明:免费下载仅供个人和非商业用途。 21. All3dfree.net 就像网站名称一样,它提供免费的3D模型,还包括Vray材料,CAD块,2d和3d纹理集合,无需注册即可免费下载。它是不断更新的,因此您可以查找或请求3DS,MAX,C4D,skp,OBJ,FBX,MTL等格式的模型。 使用说明:所有资源均不允许用于商业用途,否则您将承担责任。 22. Hum3D 自2005年以来,Hum3D帮助来自3多个国家的80D艺术家节省3D建模时间,并制作逼真的3D模型,用于电影,视频游戏,AR应用程序和可视化。所有模型均由首席3D艺术家进行验证,他们检查其是否符合专业要求和最新的3D建模标准。 使用说明:免费下载仅供个人和非商业用途。 23. Artist-3D.com 艺术家-3D 库存的免费 3D 模型下载按通用类别排序。它为人体解剖学、汽车、家具、火箭、卫星等模型提供 AutoDesk 3DS Max 格式。您还可以在浏览他们的网站时找到教程和类似类型的建模。 使用说明:使用权限可能因型号而异。因此,在下载文件之前,请仔细检查每个下载页面上的许可证和使用权限。 24. Free the models 就像本网站的标题一样,它为3d应用程序和3d游戏引擎提供免费的内容模型。您可以为您的任何项目找到许多有趣且有用的模型!它提供3ds,wavefront,bryce,poser,lightwave,md2和unity3d格式的模型。还有一个很棒的纹理集合,可以在您最喜欢的建模和渲染程序中使用。 使用说明:您从这里下载的所有内容都可以免费使用,除非它不能包含在另一个免费的网络或CD收藏中,也不能单独出售。否则,您可以在商业游戏,3D应用程序或渲染作品中使用它。您不必提供信用,但如果您这样做,那就太好了。 25. Resources.blogscopia 本网站由一家名为Scopia的公司创建。他们制作3D图像和视频,您可以找到许多为CGI工作的信息架构设计的模型,所有这些都可以在现实生活中使用。您可以免费下载它们,但是,如果您想一次下载它们,您可以支付 3 到 9 欧元。 使用说明:您可以免费下载模型部分的所有文件。每个压缩文件都包含您也可以在此处找到的许可证。基本上,您可以对文件执行任何操作。唯一的限制是不归属于Scopia的重新分发。 26.ambientCG 1000+公共领域PBR材料适合所有人!环境CG是使用许多不同的方法和资产类型创建的,例如照片纹理(PBR),贴花(PBR),图集(PBR),照片纹理(普通),物质存档(SBSAR),雕刻画笔,3D模型和地形。您可以在所有项目中*使用它们! 使用说明:在 ambientCG 上提供下载的所有 PBR 材料、画笔、照片和 3D 模型均根据知识共享 CC0 1.0 通用许可提供。您可以复制、修改、分发和执行作品,即使是出于商业目的,也无需征得许可。信用将不胜感激。 不要满足于平庸的大理石纹理 - 立即使用我们的免费PBR大理石纹理升级您的3D设计。 27.Pixar One Twenty Eight 这是一个提供官方动画行业经典纹理的网站:皮克斯,创建于 1993 年,该纹理库包括 128 个重复纹理,现在免费提供。 它包含您来到的纹理,包括砖块和动物毛皮。肯定会有一些你可以使用的东西。 使用说明:皮克斯动画工作室的《Pixar One Twenty Eight》根据知识共享署名4.0国际许可协议进行许可。即使出于商业目的,您也可以重新混合、调整和构建您的作品,只要您以相同的条款对新创作进行信用和许可。 访问数以千计的免费纹理并提升您的设计游戏 - 立即开始下载! 28. 3DXO 即使有近 620 个免费贴纸可供下载,3DXO 也不是最大的资源,但它的内容非常有用,不需要注册。无论是简单的墙壁或地板,还是一些奇怪的小东西,您都需要的纹理都可以在此网站上看到。 使用说明:使用权限可能因型号而异。因此,在下载文件之前,请仔细检查每个下载页面上的许可证和使用权限。 29. 3DModelsCC0 3DModelsCC0 与其他产品的不同之处在于它包含超过 250+ 个高质量 3D 模型,并且本网站上的所有内容都是免费的,完全是公共领域!使用我们的模型时无需信用或归属! 使用说明:为每个人提供完全免费的公共领域内容。 30.Sketch up texture club Sketchup Texture Club是一个非营利性的教育和信息门户网站,由3D社区的图像促进协会管理,特别强调面向学生和建筑和室内设计专业人士的可视化和渲染技术,以及所有正在学习3D可视化的人。 使用说明:您无需支付版税或使用费。纹理可以免费下载和使用。不允许将纹理作为竞争产品出售或重新分发,即使图像被修改也是如此。 31. FlippedNormals FlippedNormal 是一个提供计算机图形和 3D 资产的市场,您可以找到许多用于雕刻、建模、纹理、概念艺术、3D 模型、游戏资产或课程的高级资产! 使用说明:使用权限可能因型号而异。因此,在下载文件之前,请仔细检查每个下载页面上的许可证和使用权限。 32. NASA 3D NASA 3D网站是一个在线门户,提供与太空和各种NASA任务相关的大量三维模型和模拟。该网站是用户友好的,并提供有关每个型号的详细信息。该网站允许用户探索和下载几种不同格式的模型,包括 OBJ、STL 和 FBX,只需单击下载按钮即可。 使用说明: 要下载模型,只需单击模型页面上的下载按钮并选择所需的格式。 33. 3DAGOGO (Astroprint) 3DAGOGO 是一个提供广泛 3D 模型的网站,包括角色、车辆和建筑物。3DAGOGO 的独特功能之一是它专注于适合 3D 打印的模型,使其成为希望创建物理原型或模型的设计师的绝佳资源。要使用 3DAGOGO,设计师只需在网站上搜索他们正在寻找的模型类型,然后下载 STL 格式的文件。 使用说明: 要使用 3DAGOGO,只需搜索所需的 3D 模型类型并下载 STL 格式的文件。根据需要自定义模型,并确保在将其用于商业目的之前检查使用权限。 34. FreeCAD FreeCAD是一款了不起的3D建模软件,可让您在计算机上创建令人难以置信的3D设计。该软件可免费下载和使用,它提供了广泛的工具和功能,可用于创建用于各种目的的3D模型。 该网站易于浏览,您可以找到开始使用FreeCAD的所有必要信息。此外,该网站还提供一系列教程和指南,可帮助您了解 3D 建模的来龙去脉。 使用说明: 要下载模型,请访问网站并从库中选择所需的模型。该网站还提供了一系列使用该软件的教程和指南。 35. Pinshape Pinshape是一个提供一系列3D打印模型的网站。网站上提供的型号质量很高,因此您可以确保您的最终印刷产品看起来很棒。该网站提供了广泛的模型,包括从家居用品到小雕像和珠宝的所有物品。 但这还不是Pinshape所能提供的全部!该网站还允许用户上传和共享自己的3D模型。这意味着您不仅可以下载出色的模型,还可以通过分享自己的设计为社区做出贡献。此外,Pinshape 提供了一系列自定义选项,因此您可以调整和调整模型以满足您的特定需求。 使用说明: 要下载模型,请在网站上创建一个帐户,搜索所需的模型,然后单击下载按钮。该网站还为每种型号提供了一系列定制选项。 36.Yeggi Yeggi 提供了大量免费的 3D 模型,您可以下载各种格式的模型,例如 STL、OBJ 和 FBX。该网站易于使用,您可以按关键字、类别或特定网站搜索模型。 Yeggi 对于任何寻找 3D 模型的人来说都是一个很好的资源。它提供了大量的模型集合,从日常物品到复杂的机械,以及介于两者之间的一切。该网站的收藏量在不断增长,每天都有新的型号增加。 使用说明: 要下载模型,请在网站上搜索所需的模型,然后单击下载按钮。该网站还提供指向托管模型的原始网站的链接。 37. Open3DModel 来自开放3D模型的图像 Open3DModel具有各种类别的模型,包括建筑,车辆和角色。无论您需要建筑物,汽车还是人的3D模型,都可以在此网站上找到。 该网站易于浏览,您可以按类别或关键字搜索模型。每个模型都附带预览图像和详细信息,例如文件格式、大小和多边形数量。此信息可以帮助您选择适合您需求的模型。 使用说明: 要下载模型,请访问网站,从库中选择所需的模型,然后单击下载按钮。 使用最好的 3D 资产管理工具简化您的 3D 制作流程。立即试用它们,将您的 3D 项目提升到一个新的水平! 38. 3DExport 对于那些为其 3D 设计项目寻找 3D 模型、纹理和其他资源的人来说,该平台是一个很好的资源。该网站有大量模型可供选择,包括 3D 打印对象、游戏资产等。用户可以按类别、文件格式或价格范围浏览,以找到适合其项目的完美资源。此外,3DExport 还提供一系列教程和其他 3D 资源,以帮助用户提高技能并创建更令人印象深刻的设计。 使用说明: 要使用 3DExport,只需创建一个帐户并浏览可用型号。您可以按类别、格式和价格进行搜索,以找到所需的型号。找到喜欢的模型后,只需下载它并开始在您的项目中使用它。 39.Blend Swap Blend Swap是一个社区驱动的市场,提供与Blender软件兼容的各种免费3D模型。该平台允许用户共享和下载模型、纹理和其他资产,以便在他们的项目中使用。 使用说明: 创建免费帐户后,您可以浏览社区上传的大量3D模型。当您找到要使用的一个时,只需下载它并将其导入您选择的 3D 软件即可。 40. 3DShook 3DShook 是一个高级 3D 模型市场,提供一系列用于建筑、游戏等各个行业的高质量模型。该平台提供基于订阅的模型,具有不同的定价计划,允许用户访问一系列模型。 使用说明: 注册免费帐户后,只需浏览3D模型库,选择您喜欢的模型,然后以您需要的格式下载它们。 41. Smithsonian X 3D 史密森尼 X 3D 对于正在寻找历史文物和文物的高质量 3D 模型的设计师来说,这是一个独特的资源。该平台提供了大量3D模型,这些模型是根据史密森尼博物馆和研究中心中的真实物体扫描创建的。 使用说明:
-
F#探险之旅(二):函数式编程(上)-函数式编程范式简介 F#主要支持三种编程范式:函数式编程(Functional Programming,FP)、命令式编程(Imperative Programming)和面向对象(Object-Oriented,OO)的编程。回顾它们的历史,FP是最早的一种范式,第一种FP语言是IPL,产生于1955年,大约在Fortran一年之前。第二种FP语言是Lisp,产生于1958,早于Cobol一年。Fortan和Cobol都是命令式编程语言,它们在科学和商业领域的迅速成功使得命令式编程在30多年的时间里独领风骚。而产生于1970年代的面向对象编程则不断成熟,至今已是最流行的编程范式。有道是“*代有语言出,各领风骚数十年”。 尽管强大的FP语言(SML,Ocaml,Haskell及Clean等)和类FP语言(APL和Lisp是现实世界中最成功的两个)在1950年代就不断发展,FP仍停留在学院派的“象牙塔”里;而命令式编程和面向对象编程则分别凭着在商业领域和企业级应用的需要占据领先。今天,FP的潜力终被认识——它是用来解决更复杂的问题的(当然更简单的问题也不在话下)。 纯粹的FP将程序看作是接受参数并返回值的函数的集合,它不允许有副作用(side effect,即改变了状态),使用递归而不是循环进行迭代。FP中的函数很像数学中的函数,它们都不改变程序的状态。举个简单的例子,一旦将一个值赋给一个标识符,它就不会改变了,函数不改变参数的值,返回值是全新的值。 FP的数学基础使得它很是优雅,FP的程序看起来往往简洁、漂亮。但它无状态和递归的天性使得它在处理很多通用的编程任务时没有其它的编程范式来得方便。但对F#来说这不是问题,它的优势之一就是融合了多种编程范式,允许开发人员按照需要采用最好的范式。 关于FP的更多内容建议阅读一下这篇文章:Why Functional Programming Matters(中文版)。F#中的函数式编程 从现在开始,我将对F#中FP相关的主要语言结构逐一进行介绍。标识符(Identifier) 在F#中,我们通过标识符给值(value)取名字,这样就可以在后面的程序中引用它。通过关键字let定义标识符,如: let x = 42 这看起来像命令式编程语言中的赋值语句,两者有着关键的不同。在纯粹的FP中,一旦值赋给了标识符就不能改变了,这也是把它称为标识符而非变量(variable)的原因。另外,在某些条件下,我们可以重定义标识符;在F#的命令式编程范式下,在某些条件下标识符的值是可以修改的。 标识符也可用于引用函数,在F#中函数本质上也是值。也就是说,F#中没有真正的函数名和参数名的概念,它们都是标识符。定义函数的方式与定义值是类似的,只是会有额外的标识符表示参数: let add x y = x + y 这里共有三个标识符,add表示函数名,x和y表示它的参数。关键字和保留字关键字是指语言中一些标记,它们被编译器保留作特殊之用。在F#中,不能用作标识符或类型的名称(后面会讨论“定义类型”)。它们是: abstract and as asr assert begin class default delegate do donedowncast downto elif else end exception extern false finally forfun function if in inherit inline interface internal land lazy letlor lsr lxor match member mod module mutable namespace new nullof open or override private public rec return sig static structthen to true try type upcast use val void when while with yield 保留字是指当前还不是关键字,但被F#保留做将来之用。可以用它们来定义标识符或类型名称,但编译器会报告一个警告。如果你在意程序与未来版本编译器的兼容性,最好不要使用。它们是: atomic break checked component const constraint constructor continue eager event external fixed functor global include method mixinobject parallel process protected pure sealed trait virtual volatile 文字值(Literals) 文字值表示常数值,在构建计算代码块时很有用,F#提供了丰富的文字值集。与C#类似,这些文字值包括了常见的字符串、字符、布尔值、整型数、浮点数等,在此不再赘述,详细信息请查看F#手册。 与C#一样,F#中的字符串常量表示也有两种方式。一是常规字符串(regular string),其中可包含转义字符;二是逐字字符串(verbatim string),其中的(")被看作是常规的字符,而两个双引号作为双引号的转义表示。下面这个简单的例子演示了常见的文字常量表示: let message = "Hello World"r"n!" // 常规字符串let dir = @"C:"FS"FP" // 逐字字符串let bytes = "bytes"B // byte 数组let xA = 0xFFy // sbyte, 16进制表示let xB = 0o777un // unsigned native-sized integer,8进制表示let print x = printfn "%A" xlet main = print message; print dir; print bytes; print xA; print xB; main Printf函数通过F#的反射机制和.NET的ToString方法来解析“%A”模式,适用于任何类型的值,也可以通过F#中的print_any和print_to_string函数来完成类似的功能。值和函数(Values and Functions) 在F#中函数也是值,F#处理它们的语法也是类似的。 let n = 10let add a b = a + blet addFour = add 4let result = addFour n printfn "result = %i" result 可以看到定义值n和函数add的语法很类似,只不过add还有两个参数。对于add来说a + b的值自动作为其返回值,也就是说在F#中我们不需要显式地为函数定义返回值。对于函数addFour来说,它定义在add的基础上,它只向add传递了一个参数,这样对于不同的参数addFour将返回不同的值。考虑数学中的函数概念,F(x, y) = x + y,G(y) = F(4, y),实际上G(y) = 4 + y,G也是一个函数,它接收一个参数,这个地方是不是很类似?这种只向函数传递部分参数的特性称为函数的柯里化(curried function)。 当然对某些函数来说,传递部分参数是无意义的,此时需要强制提供所有参数,可是将参数括起来,将它们转换为元组(tuple)。下面的例子将不能编译通过: let sub(a, b) = a - blet subFour = sub 4 必须为sub提供两个参数,如sub(4, 5),这样就很像C#中的方法调用了。 对于这两种方式来说,前者具有更高的灵活性,一般可优先考虑。 如果函数的计算过程中需要定义一些中间值,我们应当将这些行进行缩进: let halfWay a b = let dif = b - a let mid = dif / 2 mid + a 需要注意的是,缩进时要用空格而不是Tab,如果你不想每次都按几次空格键,可以在VS中设置,将Tab字符自动转换为空格;虽然缩进的字符数没有限制,但一般建议用4个空格。而且此时一定要用在文件开头添加#light指令。作用域(Scope)作用域是编程语言中的一个重要的概念,它表示在何处可以访问(使用)一个标识符或类型。所有标识符,不管是函数还是值,其作用域都从其声明处开始,结束自其所处的代码块。对于一个处于最顶层的标识符而言,一旦为其赋值,它的值就不能修改或重定义了。标识符在定义之后才能使用,这意味着在定义过程中不能使用自身的值。 let defineMessage = let message = "Help me" print_endline message // error 对于在函数内部定义的标识符,一般而言,它们的作用域会到函数的结束处。 但可使用let关键字重定义它们,有时这会很有用,对于某些函数来说,计算过程涉及多个中间值,因为值是不可修改的,所以我们就需要定义多个标识符,这就要求我们去维护这些标识符的名称,其实是没必要的,这时可以使用重定义标识符。但这并不同于可以修改标识符的值。你甚至可以修改标识符的类型,但F#仍能确保类型安全。所谓类型安全,其基本意义是F#会避免对值的错误操作,比如我们不能像对待字符串那样对待整数。这个跟C#也是类似的。 let changeType = let x = 1 let x = "change me" let x = x + 1 print_string x 在本例的函数中,第一行和第二行都没问题,第三行就有问题了,在重定义x的时候,赋给它的值是x + 1,而x是字符串,与1相加在F#中是非法的。 另外,如果在嵌套函数中重定义标识符就更有趣了。 let printMessages = let message = "fun value" printfn "%s" message; let innerFun = let message = "inner fun value" printfn "%s" message innerFun printfn "%s" message printMessages 打印结果: fun value inner fun valuefun value 最后一次不是inner fun value,因为在innerFun仅仅将值重新绑定而不是赋值,其有效范围仅仅在innerFun内部。递归(Recursion)递归是编程中的一个极为重要的概念,它表示函数通过自身进行定义,亦即在定义处调用自身。在FP中常用于表达命令式编程的循环。很多人认为使用递归表示的算法要比循环更易理解。 使用rec关键字进行递归函数的定义。看下面的计算阶乘的函数: let rec factorial x = match x with | x when x < 0 -> failwith "value must be greater than or equal to 0" | 0 -> 1 | x -> x * factorial(x - 1) 这里使用了模式匹配(F#的一个很棒的特性),其C#版本为: public static long Factorial(int n) { if (n < 0) { throw new ArgumentOutOfRangeException("value must be greater than or equal to 0"); } if (n == 0) { return 1; } return n * Factorial (n - 1); } 递归在解决阶乘、Fibonacci数列这样的问题时尤为适合。但使用的时候要当心,可能会写出不能终止的递归。匿名函数(Anonymous Function) 定义函数的时候F#提供了第二种方式:使用关键字fun。有时我们没必要给函数起名,这种函数就是所谓的匿名函数,有时称为lambda函数,这也是C#3.0的一个新特性。比如有的函数仅仅作为一个参数传给另一个函数,通常就不需要起名。在后面的“列表”一节中你会看到这样的例子。除了fun,我们还可以使用function关键字定义匿名函数,它们的区别在于后者可以使用模式匹配(本文后面将做介绍)特性。看下面的例子: let x = (fun x y -> x + y) 1 2let x1 = (function x -> function y -> x + y) 1 2let x2 = (function (x, y) -> x + y) (1, 2) 我们可优先考虑fun,因为它更为紧凑,在F#类库中你能看到很多这样的例子。 注意:本文中的代码均在F# 1.9.4.17版本下编写,在F# CTP 1.9.6.0版本下可能不能通过编译。 F#系列随笔索引页面