在云端,看梦想

Welcome to LiZhi's Blog!

代码即文章,每个程序员都应该是个优秀的作家!

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  1 /*
  2  *
  3  * iec61850sv_protocol.h
  4  *
  5  * iec61850采样协议(9-1、9-2)解析。
  6  *
  7  *
  8  * 本代码支持win32平台和linux平台。
  9  *
 10  * Copyright (c)2012,lizhi<ibox>
 11  *
 12  * 2012-10-10 V1.0 lizhi<QQ:252240557,msn:ddgooo@hotmail.com> created
 13  *
 14  *
 15  * ◆ IEC61850-9-2(特定通信服务映射-基于ISO/IEC 8802-3 的模拟量采样值)
 16  * 以太网通信帧结构格式(9-1、9-2):
 17  *       Header MAC      01     目标地址        0xFF
 18  *                       02                     0xFF
 19  *                       03                     0xFF
 20  *                       04                     0xFF
 21  *                       05                     0xFF
 22  *                       06                     0xFF
 23  *                       07     源地址          0x73
 24  *                       08                     0x61
 25  *                       09                     0x63
 26  *                       10                     0x00
 27  *                       11                     0x00
 28  *                       12                     0x01
 29  *       Priority Tagged 13     TPID            0x81
 30  *                       14                     0x00
 31  *                       15     TCI             0x80
 32  *                       16                     0x00
 33  *       Ether-type PDU  17     Ether-type      0x88
 34  *                       18                     0xBA
 35  *                       19     APPID           0x40
 36  *                       20                     0x00
 37  *                       21     Length          ....
 38  *                       22                     ....
 39  *                       23     保留            0x00
 40  *                       24                     0x00
 41  *                       25     保留            0x00
 42  *                       26                     0x00
 43  *       APDU            27 ~ N 格式见后面      ....
 44  *
 45  * 【9-2】APDU的内容定义(第27个字节开始):
 46  * 其中Len表示asn1的长度, 注意计算方法.
 47  * 长度在[0, 7f], 1个字节表示
 48  * 长度在[80, ff], 2个字节表示,第一个字节填0x81
 49  * 长度在[100, ffff], 3个字节表示,第一个字节填0x82, 后面用网络字节序
 50  * ASDU个数可配,至多12个,采样频率SampleRate范围[1, 255]。SmpCnt前后两报文之间加一,当达到采样率时(或溢出时)归零(归1)。
 51  *
 52  * APDU的内容定义:
 53  *      1       savPdu          0x60    Len
 54  *      2       numOfAsdu                       0x80    Len=1   AsduNum
 55  *      2 SequenceOfAsdu                        0xA2    Len
 56  *      3 Sequence Asdu1                                        0x30    Len     Asdu1
 57  *      3 Sequence Asdu2                                        0x30    Len     Asdu2
 58  *      ....                                                    ...     ...     ...
 59  *
 60  * ASDU内容:
 61  *       0x80 svID      Len=[10, 34]    10~34个字符串
 62  *       0x82 smpCnt    Len=2           计数, 变化值
 63  *       0x83 confRev   Len=1           配置版本
 64  *       0x85 smpSynch  Len=1           同步标识
 65  *       0x87 Dataset   Len=64          见下面, 变化值
 66  *                                               4bytes UA
 67  *                                               4bytes UA Quality
 68  *                                               4bytes UB
 69  *                                               4bytes UB Quality
 70  *                                               4bytes UC
 71  *                                               4bytes UC Quality
 72  *                                               4bytes UZ
 73  *                                               4bytes UZQuality
 74  *                                               4bytes IA
 75  *                                               4bytes IA Quality
 76  *                                               4bytes IB
 77  *                                               4bytes IB Quality
 78  *                                               4bytes IC
 79  *                                               4bytes IC Quality
 80  *                                               4bytes IZ
 81  *                                               4bytes IZ Quality
 82  *
 83  *采样质量编码参见 IEC61850-7-3 质量的编码。
 84  *
 85  *
 86  * 【9-1】APDU的内容定义(第27个字节开始):
 87  *      1 savPdu          0x80(TAG)    ASDU Length(asn1长度)
 88  *      2 numOfAsdu                       No. of ASDUs(asn1长度)
 89  *      3 Sequence Asdu1                  Asdu1(46字节)
 90  *      3 Sequence Asdu2                  Asdu2(46字节)
 91  *      ....                              ...
 92  *
 93  * ASDU内容:
 94  *      ASDU 报头         01      ASDU 长度(44)                             0x00
 95  *                        02                                                0x2c
 96  *      ASDU(基本数据集)  03      LNName(逻辑节点名总为02)                  0x02
 97  *                        04      DataSetName(数据集名称为01或者FE)         0x01
 98  *                        05      LDName(逻辑设备名)                        ...
 99  *                        06                                                ...
100  *                        07      额定相电流                                ...
101  *                        08                                                ...
102  *                        09      额定中线电流                              ...
103  *                        10                                                ...
104  *                        11      额定相电压                                ...
105  *                        12                                                ...
106  *                        13      额定时延                                  ...
107  *                        14                                                ...
108  *                        15      A 相电流, 保护用                          ...
109  *                        16                                                ...
110  *                        17      B 相电流, 保护用                          ...
111  *                        18                                                ...
112  *                        19      C 相电流, 保护用                          ...
113  *                        20                                                ...
114  *                        21      中线电流                                  ...
115  *                        22                                                ...
116  *                        23      A 相电流, 仪表用                          ...
117  *                        24                                                ...
118  *                        25      B 相电流, 仪表用                          ...
119  *                        26                                                ...
120  *                        27      C 相电流, 仪表用                          ...
121  *                        28                                                ...
122  *                        29      A 相电压                                  ...
123  *                        30                                                ...
124  *                        31      B 相电压                                  ...
125  *                        32                                                ...
126  *                        33      C 相电压                                  ...
127  *                        34                                                ...
128  *                        35      零序电压                                  ...
129  *                        36                                                ...
130  *                        37      母线电压                                  ...
131  *                        38                                                ...
132  *                        39      状态字#1                                  ...
133  *                        40                                                ...
134  *                        41      状态字#2                                  ...
135  *                        42                                                ...
136  *                        43      采样计数器                                ...
137  *                        44                                                ...
138  *                        45      采样率                                    ...
139  *                        46      配置版本号                                ...
140  *
141  *
142  */
143 
144 
145 #ifndef __INCLUDE_SVPDU_PROTOCOL_H
146 #define __INCLUDE_SVPDU_PROTOCOL_H
147 
148 
149 /*
150  * 头文件
151  */
152 #include "base_type.h"
153 
154 
155 #if defined (__cplusplus)
156 extern "C" {
157 #endif /* defined (__cplusplus) */
158 
159 
160 /*
161  * 宏开关
162  */
163 #ifndef SVPDU_IOBUFFER
164 #define SVPDU_IOBUFFER
165 #endif
166 
167 /*
168  * 宏定义文件的读写操作,可以根据需要改写该接口,如重定义
169  * 为网口的recv\send、串口r\w等。
170  *
171  * _my_read_svpdu_bufn/_my_read_svpdu_bufn - svpdu的读写操作
172  * @pfd: 读写地址,可以为文件的fd、或者buffer地址等
173  * @buf: 缓冲区地址
174  * @count: 需要读写的字节数
175  *
176  */
177 #if defined(SVPDU_IOFILE)
178 typedef int _my_svpdu_ioptr;
179 #define _my_read_svpdu_bufn(pfd, buf, count)                    \
180         do {                                                    \
181                 if (read((pfd), (buf), (count)) <= 0) {         \
182                         (pfd) = -1;                             \
183                 }                                               \
184         } while(0);
185 #define _my_write_svpdu_bufn(pfd, buf, count)                   \
186         do {                                                    \
187                 if (write((pfd), (buf), (count)) <= 0) {        \
188                         (pfd) = -1;                             \
189                 }                                               \
190         } while(0);
191 #define _my_check_svpdu_ptr(pfd)                                \
192         (((pfd) != -1) && ((pfd) != 0))
193 #elif defined(SVPDU_IOBUFFER)
194 typedef u8* _my_svpdu_ioptr;
195 #define _my_read_svpdu_bufn(pfd, buf, count)                    \
196         do {                                                    \
197                 memcpy((buf), (pfd), (count));                  \
198                 (pfd) += (count);                               \
199         } while(0);
200 #define _my_write_svpdu_bufn(pfd, buf, count)                   \
201         do {                                                    \
202                 memcpy((pfd), (buf), (count));                  \
203                 (pfd) += (count);                               \
204         } while(0);
205 #define _my_check_svpdu_ptr(pfd)                                \
206         (((pfd) != -1) && ((pfd) != 0))
207 #endif
208 
209 
210 /*
211  * 关于链路层svpdu报文头部信息的宏定义
212  */
213 /*
214  * SVPDU_LPDU_TPID_VLAN - tpid的宏定义,标记的协议标识(Tag Protocol Identifier),虚拟局域网(Virtual Local
215  *              Area Network);
216  */
217 #define SVPDU_LPDU_TPID_VLAN                    0x8100
218 /*
219  * svpdu_tci_get_pri/svpdu_tci_set_pri - 关于tci中PRI的取值/赋值的宏定义,
220  *              PRI:User priority(优先权),占前3bit(BS3),如果不配置优先级,则应采用以下的缺省值为4
221  *              (即二进制100);
222  */
223 #define svpdu_tci_get_pri(tci)                  (((tci) & 0xE000) >> 13)
224 #define svpdu_tci_set_pri(tci,pri)              ((((pri) << 13) | 0x1FFF) & ((tci) | 0xE000))
225 /*
226  * svpdu_lpdu_tci_get_cfi/svpdu_tci_set_cfi - 关于tci中CFI的取值/赋值的宏定义;占PRI后面1bit;
227  *
228  */
229 #define svpdu_tci_get_cfi(tci)                  (((tci) & 0x1000) >> 12)
230 #define svpdu_tci_set_cfi(tci,cfi)              ((((cfi) << 12) | 0xEFFF) & ((tci) | 0x1000))
231 /*
232  * svpdu_tci_get_vid/svpdu_tci_set_vid - 关于tci中VID的取值/赋值的宏定义;占之后剩下的12bit;
233  *
234  */
235 #define svpdu_tci_get_vid(tci)                  ((tci) & 0x0FFF)
236 #define svpdu_tci_set_vid(tci,vid)              (((tci) | 0xF000) & ((tci) | 0x0FFF))
237 
238 /*
239  * SVPDU_ETHER_TYPE_XXX - 关于ether type的宏定义
240  * SVPDU_ETHER_TYPE_81_GOOSE - IEC 61850-8-1 GOOSE
241  * SVPDU_ETHER_TYPE_81_GSE - IEC 61850-8-1 GSE
242  * SVPDU_ETHER_TYPE_91_OR_92 - IEC 61850-9-1/9-2 采样值
243  */
244 #define SVPDU_ETHER_TYPE_81_GOOSE               0x88B8
245 #define SVPDU_ETHER_TYPE_81_GSE                 0x88B9
246 #define SVPDU_ETHER_TYPE_91_OR_92               0x88BA
247 /*
248  * SVPDU_APPID_XXX - 关于appid的宏定义;APPID用以选择采样值信息并区分应用关联。APPID的值是APPID类型
249  *              码和实际标识的组合,APPID类型码被定义为其最高两位;为采样值保留的取值范围为 0x4000
250  *              到0x7fff;如果没有配置APPID,缺省值应为0x4000。缺省值被保留为表明缺少配置;
251  * SVPDU_APPID_TYPE_81_GOOSE_OR_GSE - IEC 61850-8-1 GOOSE/GSE APPID type;
252  * SVPDU_APPID_TYPE_91_OR_92 - IEC 61850-9-1/9-2 APPID type;
253  * SVPDU_APPID_DEFAULT - 缺省值;
254  * svpdu_appid_get_type - 取类型码值;
255  * svpdu_appid_set_type - 赋值类型码;
256  *
257  */
258 #define SVPDU_APPID_TYPE_81_GOOSE_OR_GSE        0x00
259 #define SVPDU_APPID_TYPE_91_OR_92               0x01
260 #define SVPDU_APPID_DEFAULT                     0x4000
261 #define svpdu_appid_get_type(appid)             (((appid) & 0xC000) >> 14)
262 #define svpdu_appid_set_type(appid,type)        ((((type) << 14) | 0x3FFF) & ((appid) | 0xC000))
263 
264 /*
265  * svpdu_lpdu_head - 9-2/9-1采样值(sample value)链路层(link layer)报文(pdu)头部信息。
266  * @des_mac: 目标地址(为FF:FF:FF:FF:FF:FF表示广播包),ISO/IEC8802-3标准地址;
267  * @src_mac: 源地址,ISO/IEC8802-3标准地址;
268  * @tpid: 标记的协议标识(Tag Protocol Identifier),有些报文没有该字段(非标准的);
269  * @tci: 标记的控制信息(Tag Control Information),有些报文没有该字段(非标准的);
270  * @ether_type: 以太网类型;
271  * @appid: 应用标识,标识不用的应用的采样值,连续几个包取得采样值时需要核对应用标识,否则会导致取得采
272  *              样值混乱;
273  * @epdu_length: 包括以APPID开始的以太网类型PDU在内的八位位组的数目,其值为8+m(m<1480);
274  * @reserve1: 保留字节,为0;
275  * @reserve2: 保留字节,为0;
276  *
277  * TPID 值:0x8100;
278  * TCI 值: 由三部分组成:
279  *      PRI:User priority(优先权),占前3bit(BS3),应对user priority值进行配置,以区分采样值和定时苛
280  *           刻的、保护相关的GOOSE信息,或低优先级的总线负载。如果不配置优先级,则应采用缺省值(4);
281  *      CFI:占PRI后面1bit,用于标识是否含有RIF信息;在以太网标记帧中长度/类型域后没有嵌入RIF域,值应
282  *           该为0;若值为1,则表明在ISO/IEC8802-3标记帧中,Length/Type域后接着内嵌的路由信息域(RIF);
283  *      VID: 占之后剩下的12bit;为支持虚拟局域网是一种可选的机制,如果采用了这种机制,那么配置时应设
284  *           定虚拟局域网标识(VID)。另外,虚拟局域网标识VID 缺省值为0;
285  * 注:IEEE802.1Q允许应用带有一组优先级限制,高优先级帧应设置其优先级为4~7,低优先级帧则为1~3,优
286  *     先级1为未标记的帧,应避免采用优先级0,因为这会引起正常通信下不可预见的传输时延。优先级和虚拟
287  *     网标识(VID)的缺省值表:优先级和虚拟网标识(VID)的缺省值
288  *               服务      VID缺省值  优先级缺省值
289  *               采样值    0          4
290  * ETHER_TYPE 值: 以太网类型码16位表示,下表描述[以太网类型码]取值和[APPID类型码]取值;
291  *      表:分配的以太网类型码取值([APPID类型码]指APPID的最高两位)
292  *              应用                    以太网类型码取值(16进制)        APPID类型
293  *              IEC61850-8-1GOOSE       88-B8                           0 0
294  *              IEC61850-8-1GSE管理     88-B9                           0 0
295  *              IEC61850-9-1采样值      88-BA                           0 1
296  *              IEC61850-9-2采样值      88-BA                           0 1
297  * APPID 值:应用标识。APPID 用以选择采样值信息并区分应用关联。APPID的值是[APPID 类型码]和[实际标识]
298  *      的组合,APPID 类型码被定义为其最高两位(如表8 所定义)。因而采样值取如下值:
299  *      为采样值保留的取值范围为 0x4000~0x7fff。如果没有配置APPID,缺省值应为0x4000。缺省值被保留为
300  *      表明缺少配置。强烈推荐在同一系统内采用唯一的、面向数据源的采样值应用标识(SV APPID)。这应当由
301  *      配置系统强迫执行。
302  *
303  */
304 struct svpdu_lpdu_head {
305         u8 des_mac[6];
306         u8 src_mac[6];
307         u16 tpid;
308         u16 tci;
309         u16 ether_type;
310         u16 appid;
311         u16 epdu_length;
312         u16 reserve1;
313         u16 reserve2;
314 };
315 
316 
317 /*
318  * SVPDU_APDU_TAG_91/SVPDU_APDU_TAG_92 - 应用层协议标识,可用来区分该数据包类型;
319  */
320 #define SVPDU_APDU_TAG_91                       0x80
321 #define SVPDU_APDU_TAG_92                       0x60
322 /*
323  * SVPDU_ASDUNUM_TAG_92 - asdu个数标识(9-2)
324  */
325 #define SVPDU_ASDUNUM_TAG_92                    0x80
326 /*
327  * SVPDU_SECURITY_TAG_92 - 安全信息标识(9-2)
328  */
329 #define SVPDU_SECURITY_TAG_92                   0x81
330 /*
331  * SVPDU_SEQUENCE_TAG_92 - 关于sequence of asdu的宏定义
332  */
333 #define SVPDU_SEQUENCE_TAG_92                   0xA2
334 
335 /*
336  * svpdu_apdu_head - 9-2/9-1 svpdu中应用层(Application Layer)apdu头部信息;
337  * @apdu_tag: 应用层协议标识;为0x60时为9-2数据,为0x80时为9-1数据,该标识可以用来区分该数据包类型;
338  * @apdu_length: apdu数据包的长度值(从apdu_length的下一个数据开始计数);该数据本身是变长数据,采用
339  *              ASN.1 基本编码规则(ISO/IEC 8825-1),在此约定该值不会超过0xffffff,最长为4字节,采用u32
340  *              类型数据存储;
341  * @asdu_num_tag: asdu个数标识;该值在9-2中为0x80,9-1中没有该标识;
342  * @asdu_num_length: [asdu个数]的长度值;标识num数据本身的长度信息,该值在9-2中一般为0x01,9-1中没有
343  *              该标识;该数据本身是变长数据,采用ASN.1编码;在此约定该值不会超过0xffffff,最长为4
344  *              字节(实际一般为1在字节),采用u32类型数据存储;
345  * @asdu_num_value: asdu个数;该值在9-2中,该数据是变长数据,长度(字节数)由asdu_num_length中的len
346  *              值(不是码)决定;在9-1中,固定采用2字节表示;在此直接用2字节表示,应为其值一般不能
347  *              超过2字节;
348  * @asdu_security_tag: 安全信息标识;该值在9-2中为0x81,为可选数据(一般不选);在9-1中无该数据;
349  * @asdu_security_length: 安全信息长度;采用ASN.1编码,变长,该项在9-2中为可选数据(一般不选),其值一
350  *              般为0;在9-1中无该数据;在此约定该值不会超过0xffffff,最长为4字节,采用u32类型数据存储;
351  * @asdu_sequence_tag: asdu序列信息标识;该值在9-2中为0xA2;在9-1中无该数据;
352  * @asdu_sequence_length: asdu序列信息长度;采用ASN.1编码,变长;在9-1中无该数据;在此约定该值不会超过
353  *              0xffffff,最长为4字节,采用u32类型数据存储;
354  *
355  * 注:
356  * 结构体中的ASN.1长度码统一采用u32表示,计算实际长度值时,需要解码;ASN.1长度计算方法如下:
357  *      长度值在[0x000000, 0x00007f],1个字节表示;
358  *      长度值在[0x000080, 0x0000ff],2个字节表示,第一个字节填0x81;
359  *      长度值在[0x000100, 0x00ffff],3个字节表示,第一个字节填0x82,后面用网络字节序;
360  *      长度值在[0x010000, 0xffffff],4个字节表示,第一个字节填0x83,后面用网络字节序;
361  * 一般情况下,asdu_security_tag、asdu_security_length没有;
362  * 61850编码规则基于ASN.1基本编码规则(BER),传输语法采用8位位组和面向“Big Endian(高字节在前)”的。
363  *
364  */
365 struct svpdu_apdu_head {
366         u8  apdu_tag;
367         u32 apdu_length;
368         u8  asdu_num_tag;
369         u32 asdu_num_length;
370         u16 asdu_num_value;
371         u8  asdu_security_tag;
372         u32 asdu_security_length;
373         u8  asdu_sequence_tag;
374         u32 asdu_sequence_length;
375 };
376 
377 
378 /*
379  * SVPDU_ASDU_TAG_92 - asdu标识(9-2),
380  */
381 #define SVPDU_ASDU_TAG_92                       0x30
382 /*
383  * SVPDU_ASDU_XXX_TAG_92 - 表示9-2中SVID、DATSET、SMPCNT、CONFREV、REFRTM、SMPSYNCH、SMPRATE以及
384  *              SMPDATA项的标识;
385  */
386 #define SVPDU_ASDU_SVID_TAG_92                  0x80
387 #define SVPDU_ASDU_DATSET_TAG_92                0x81
388 #define SVPDU_ASDU_SMPCNT_TAG_92                0x82
389 #define SVPDU_ASDU_CONFREV_TAG_92               0x83
390 #define SVPDU_ASDU_REFRTM_TAG_92                0x84
391 #define SVPDU_ASDU_SMPSYNCH_TAG_92              0x85
392 #define SVPDU_ASDU_SMPRATE_TAG_92               0x86
393 #define SVPDU_ASDU_SMPDATA_TAG_92               0x87
394 
395 /*
396  * svpdu_asdu_dat92 - IEC61850-9-2中的asdu详细信息;具体可以包括SVID、DATSET、SMPCNT、CONFREV、
397  *              REFRTM、SMPSYNCH、SMPRATE以及SMPDATA项标记、长度、值的详细信息;
398  * @asdu_tag: asdu标记,详见宏定义值;
399  * @asdu_length: asdu总的长度信息;
400  * @svid_tag: svid标记,值为0表示不包含该项信息;
401  * @svid_length: svid信息长度;
402  * @svid_value: svid信息值,系统中唯一标识,该值为VisibleString类型;
403  * @datset_tag: datset标记,值为0表示不包含该项信息;
404  * @datset_length: datset信息长度;
405  * @datset_value: datset信息值,来自MSVC或者USVC的值,为ObjectReference类型;
406  * @smpcnt_tag: smpcnt标记,值为0表示不包含该项信息;
407  * @smpcnt_length: smpcnt信息长度;
408  * @smpcnt_value: smpcnt信息值;
409  * @confrev_tag: confrev标记,值为0表示不包含该项信息;
410  * @confrev_length: confrev信息长度;
411  * @confrev_value: confrev信息值;
412  * @refrtm_tag: refrtm标记,值为0表示不包含该项信息;
413  * @refrtm_length: refrtm信息长度;
414  * @refrtm_value: refrtm信息值;
415  * @smpsynch_tag: smpsynch标记,值为0表示不包含该项信息;
416  * @smpsynch_length: smpsynch信息长度;
417  * @smpsynch_value: smpsynch信息值;
418  * @smprate_tag: smprate标记,值为0表示不包含该项信息;
419  * @smprate_length: smprate信息长度;
420  * @smprate_value: smprate信息值;
421  * @smpdata_tag: smpdata标记,值为0表示不包含该项信息;
422  * @smpdata_length: smpdata信息长度;
423  * @smpdata_portnum: 采样值的端口数;
424  * @smpdata_values: 采样值详细;
425  * @smpdata_qualitys: 采样质量详细,为NULL表示没有质量信息;
426  *
427  * 注:
428  * 按照协议上来说,一个asdu包不可同时包含两个相同的项(即同时有两个svid或者smpdata项),在次如果存
429  * 在这种情况,第二个相同项将不再解析;
430  * 需要注意的是,在此程序中默认tag值为0时表示不包含该项信息。
431  *
432  */
433 struct svpdu_asdu_dat92 {
434         u8  asdu_tag;
435         u32 asdu_length;
436         u8  svid_tag;
437         u32 svid_length;
438         u8 *svid_value;
439         u8  datset_tag;
440         u32 datset_length;
441         u8 *datset_value;
442         u8  smpcnt_tag;
443         u32 smpcnt_length;
444         u16 smpcnt_value;
445         u8  confrev_tag;
446         u32 confrev_length;
447         u32 confrev_value;
448         u8  refrtm_tag;
449         u32 refrtm_length;
450         u32 refrtm_value;
451         u8  smpsynch_tag;
452         u32 smpsynch_length;
453         u8  smpsynch_value;
454         u8  smprate_tag;
455         u32 smprate_length;
456         u16 smprate_value;
457         u8  smpdata_tag;
458         u32 smpdata_length;
459         u32 smpdata_portnum;
460         s32 *smpdata_values;
461         u32 *smpdata_qualitys;
462 };
463 
464 
465 /*
466  * svpdu_asdu_dat91 - IEC61850-9-1中的asdu详细信息;
467  * @asdu_length:数据集长度;类型为16位无符号整数,值域为<0..65535>;长度域包含随后的数据集长度;
468  *               这个长度不包括长度域本身。按IEC 60044-8规定,长度总是44(十进制);
469  *               如果是自定义数据集,长度会变;
470  * @ln_name:逻辑节点名称;类型为8位枚举型,值域为<0..255>;逻辑节点名总为2;
471  * @dataset_name: 数据集名(DataSetName) 类型为8枚举型,值域为<0..255>;
472  *                数据集名是唯一的数字,用于标识数据集结构,也就是数据通道的分配;
473  *                这里允许的取值有01或0xFE(十进制254);
474  *                下表(参见表10)通用数据集(=01)中定义了DataSetName为01时数据通道到信号源的分配;
475  * @ld_name:逻辑设备名(LDName) 类型为16位无符号整数,值域为<0..65535>;
476  *           逻辑设备名在一个变电站中是唯一的,用于标志数据集的来源;逻辑设备名可以在安装时设置;
477  * @i_pp: 额定相电流;数据类型为16位无符号整数,值域为<0..65535>;如果不使用,用0替代它;
478  * @i_p0: 额定中线电流(零序电流);数据类型为16位无符号整数,值域为<0..65535>;如果不使用,用0替代它;
479  * @v_pp: 额定相电压;数据类型为16位无符号整数,值域为<0..65535>;如果不使用,用0替代它;
480  * @t_delay: 额定时延;数据类型为16位无符号整数,值域为<0..65535>;
481  *           给出模数转换和数据处理带来的延时的额定值,单位是sµ。
482  *           设发数据帧开始发出时刻为tc,这一帧数据表示的电流电压在一次侧出现的时刻为tp,
483  *           则延迟时间为tc-tp。 互感器额定延迟时间为500sµ,允许误差范围-100%~+10%;
484  * @smpdata_portnum: 采样数据端口数,该参数确定smpdata_values的空间大小;
485  * @smpdata_values:采样值数组;类型为16位整数,值域为<-32768..32767>。 12个数据通道给出各个信号源的瞬时值,
486  *                  通道分配由数据集名决定,参见数据集名的说明。保护用相电流的比例因子由保护用电子式电流互感
487  *                  器额定输出值确定,测量用相电流的比例因子由测量用电子式电流互感器额定输出值确定(参见表10)。
488  * @status_wordX:类型为16位布尔量集。参见【表11】、【表12】;
489  *                如果某个数据通道未使用,则其响应的状态标志置为无效,
490  *                数据通道内容置为0x0000。 如果一个传感器故障,其相应的状态标志置为无效,
491  *                并将需要维护标志(LPHD.PHHealth)置位。 在唤醒期间数据无效,
492  *                所有的数据无效标志和唤醒指示标志都置位。 同步脉冲丢失或无效标志在下面逻辑满足时置位:
493  *                [[同步脉冲丢失 或 同步脉冲无效] 与 [合并器的内部时钟漂移大于额定相位误差限制的二分之1]]。
494  *@smp_cnt:类型为16位无符号整数,值域为<0..65535>。
495  *          这个16位采样计数器用于检查数据内容是否被连续刷新。每发送一个新的采样数据集,计数器增加1,
496  *          溢出后回到0重新开始计数。 当合并器使用同步脉冲时,合并器收到每个同步脉冲都将把采样计数器清零。
497  *          采样计数器为零的数据帧的数据对应同步脉冲发生时刻的一次电流电压。
498  *@smp_rate:数据速率;类型为8位无符号整数,值域为<0..255>;给出额定频率下每周波时间内输出的采样数据集数目,为0时无意义。
499  *           这里采样速率等于互感器的数据速率。
500  *@version:配置版本号;类型为8位无符号整数,值域为<0..255>。 在每次修改逻辑设备配置时增加1,缺省值为0。
501  *
502  * 【表10】:表DataSetName=01(通用应用)的数据通道映射
503  *                      信号源           对象路径名       参考值         比例因子(见表 3)
504  *          数据通道1   A相电流.保护用   PhsATCTR.Amps    额定相电流     SCP
505  *          数据通道2   B相电流.保护用   PhsBTCTR.Amps    额定相电流     SCP
506  *          数据通道3   C相电流.保护用   PhsCTCTR.Amps    额定相电流     SCP
507  *          数据通道4   零序电流         NeutTCTR.Amps    额定零序电流   SCM
508  *          数据通道5   A相电流.测量用   PhsA2TCTR.Amps   额定相电流     SCM
509  *          数据通道6   B相电流.测量用   PhsB2TCTR.Amps   额定相电流     SCM
510  *          数据通道7   C相电流.测量用   PhsC2TCTR.Amps   额定相电流     SCM
511  *          数据通道8   A相电压          PhsATVTR.Volts   额定相电压     SV
512  *          数据通道9   B相电压          PhsBTVTR.Volts   额定相电压     SV
513  *          数据通道10  C相电压          PhsCTVTR.Volts   额定相电压     SV
514  *          数据通道11  零序电压         NeutTVTR.Volts   额定相电压     SV
515  *          数据通道12  母线电压         BBTVTR.Volts     额定相电压     SV
516  *      注:对象路径名参见IEC 61850-9-1; DataSetName为0xFE时表示特殊应用数据集,在上表的通道映射
517  *      不能满足应用要求时使用。这时合并器将通过一定形式将数据集定义提供给二次设备;DataSetName
518  *      的值不能在运行时改变,也就时说在出厂前的设计和配置时便确定数据通道的分配。
519  *
520  * 【表11】:状态字1(StatusWord#1)
521  *              解释                                                                      备注
522  *      第0位   需要维护(LPHD.PHHealth)               0:正常
523  *                                                      1:告警(需要维护)
524  *      第1位   模式(LLN0.Mode)                       0:正常运行
525  *                                                      1:测试
526  *      第2位   唤醒期间指示 唤醒期间数据无效指示       0:正常,数据有效                 在唤醒期间被置位
527  *                                                      1:唤醒期间,数据无效
528  *      第3位   合并器同步方式                          0:不能使用插值算法同步
529  *                                                      1:可以使用插值算法同步
530  *      第4位   合并器同步标志                          0:采样已同步                     如果使用插值算法,这个位将总是1
531  *                                                      1:同步丢失或无效
532  *      第5位   数据通道1无效标志                       0:数据有效
533  *                                                      1:数据无效
534  *      第6位   数据通道2无效标志                       0:数据有效
535  *                                                      1:数据无效
536  *      第7位   数据通道3无效标志                       0:数据有效
537  *                                                      1:数据无效
538  *      第8位   数据通道4无效标志                       0:数据有效
539  *                                                      1:数据无效
540  *      第9位   数据通道5无效标志                       0:数据有效
541  *                                                      1:数据无效
542  *      第10位  数据通道6无效标志                       0:数据有效
543  *                                                      1:数据无效
544  *      第11位  数据通道7无效标志                       0:数据有效
545  *                                                      1:数据无效
546  *      第12位  电流传感器类型                          0:电流值                        在使用Rogowski线圈且没有积分环节时置位。
547  *                                                      1:电流的导数
548  *      第13位  量程标志                                0:保护电流比例因子SCP=0x01CF
549  *                                                      1:保护电流比例因子SCP=0x00E7
550  *      第14位  备用
551  *      第15位  备用
552  *
553  * 【表12】:状态字2(StatusWord#2)
554  *              解释                                                                      备注
555  *      第0位   数据通道8无效标志                       0:数据有效
556  *                                                      1:数据无效
557  *      第1位   数据通道9无效标志                       0:数据有效
558  *                                                      1:数据无效
559  *      第2位   数据通道10无效标志                      0:数据有效
560  *                                                      1:数据无效
561  *      第3位   数据通道11无效标志                      0:数据有效
562  *                                                      1:数据无效
563  *      第4位   数据通道12无效标志                      0:数据有效
564  *                                                      1:数据无效
565  *      第5-7位  备用
566  *      第8-15位 自定义
567  *
568  *
569  */
570 struct svpdu_asdu_dat91 {
571         u16  asdu_length;
572         u8 ln_name;
573         u8 dataset_name;
574         u16 ld_name;
575         u16 i_pp;
576         u16 i_p0;
577         u16 u_pp;
578         u16 t_delay;
579         u32 smpdata_portnum;
580         s16 *smpdata_values;
581         u16 status_word1;
582         u16 status_word2;
583         u16 smp_cnt;
584         u8 smp_rate;
585         u8 version;
586 };
587 
588 /*
589  * read_svpdu_lpdu_head - 取得链路层svpdu报文头部信息,没有读到的数据为其原来的值
590  * @pfd:  输入输出参数,地址
591  * @len: 输入参数,数据缓冲区长度;
592  * @head: 输出参数,svpdu_lpdu_head值
593  * @counter:  输出参数,读取的字节计数器;
594  *
595  * 读成功返回当前读pfd地址,否则返回NULL;
596  *
597  */
598 _my_svpdu_ioptr read_svpdu_lpdu_head(_my_svpdu_ioptr pfd, int len, struct svpdu_lpdu_head *head, int *counter);
599 
600 
601 /*
602  * read_svpdu_apdu_head - 取得svpdu报文中apdu头部信息,没有读到的数据为其原来的值
603  * @pfd:  输入输出参数,地址
604  * @len: 输入参数,数据缓冲区长度;
605  * @head: 输出参数,svpdu_lpdu_head值
606  * @counter:  输出参数,读取的字节计数器;
607  *
608  * 读成功返回当前读pfd地址,否则返回NULL;
609  *
610  */
611 _my_svpdu_ioptr read_svpdu_apdu_head(_my_svpdu_ioptr pfd, int len, struct svpdu_apdu_head *head, int *counter);
612 
613 /*
614  * read_svpdu_asdu_dat92 - 读取9-2-asdu详细值;
615  * @pfd:  输入输出参数,地址
616  * @len: 输入参数,数据缓冲区长度;
617  * @dat92: 输出参数,asdu详细值;
618  * @smpquality_enable: 是否有质量信息;
619  * @counter:  输出参数,读取的字节计数器;
620  *
621  * 读成功返回当前读pfd地址,否则返回NULL;
622  *
623  * 读取过程中可能会利用动态创建空间以保存svid_value、datset_value、smpdata_values、smpdata_qualitys数据;
624  *
625  */
626 _my_svpdu_ioptr read_svpdu_asdu_dat92(_my_svpdu_ioptr pfd, int len, struct svpdu_asdu_dat92 *dat92, int smpquality_enable, int *counter);
627 
628 
629 /*
630  * init_svpdu_asdu_dat92 - 初始化Dat92结构体;
631  * @dat92: 输入输出参数,asdu详细值;
632  * @setdefaultval: 参数是否赋默认值;
633  *
634  * 初始化成功返回当前dat92结构体地址,否则返回NULL;
635  *
636  */
637 struct svpdu_asdu_dat92 * init_svpdu_asdu_dat92(struct svpdu_asdu_dat92 *dat92, int setdefaultval);
638 /*
639  * free_svpdu_asdu_dat92 - 释放Dat92结构体;
640  * @dat92: 输入输出参数,asdu详细值;
641  *
642  * 初始化成功返回返回NULL,否则返回当前dat92结构体地址;
643  *
644  */
645 struct svpdu_asdu_dat92 * free_svpdu_asdu_dat92(struct svpdu_asdu_dat92 *dat92);
646 
647 /*
648  * read_svpdu_asdu_dat91 - 读取9-1-asdu详细值;
649  * @pfd:  输入输出参数,地址
650  * @len: 输入参数,数据缓冲区长度;
651  * @dat91: 输出参数,asdu详细值;
652  * @counter:  输出参数,读取的字节计数器;
653  *
654  * 读成功返回当前读pfd地址,否则返回NULL;
655  *
656  * 读取过程中可能会利用动态创建空间以保存smpdata_values数据;
657  *
658  */
659 _my_svpdu_ioptr read_svpdu_asdu_dat91(_my_svpdu_ioptr pfd, int len, struct svpdu_asdu_dat91 *dat91, int *counter);
660 
661 /*
662  * init_svpdu_asdu_dat91 - 初始化Dat91结构体;
663  * @dat92: 输入输出参数,asdu详细值;
664  *
665  * 初始化成功返回当前dat91结构体地址,否则返回NULL;
666  *
667  */
668 struct svpdu_asdu_dat91 * init_svpdu_asdu_dat91(struct svpdu_asdu_dat91 *dat91);
669 /*
670  * free_svpdu_asdu_dat91 - 释放Dat91结构体;
671  * @dat91: 输入输出参数,asdu详细值;
672  *
673  * 初始化成功返回返回NULL,否则返回当前dat91结构体地址;
674  *
675  */
676 struct svpdu_asdu_dat91 * free_svpdu_asdu_dat91(struct svpdu_asdu_dat91 *dat91);
677 
678 
679 /*
680  * write_svpdu_lpdu_head - 写svpdu_lpdu_head到文件中
681  * @pfd: 输入参数,写地址;
682  * @head:输入参数,svpdu_lpdu_head结构体;
683  * @counter: 输出参数,成功写入的字节个数;
684  *
685  * 返回当前pfd指针,写失败返回NULL
686  *
687  */
688 _my_svpdu_ioptr write_svpdu_lpdu_head(_my_svpdu_ioptr pfd, struct svpdu_lpdu_head *head, int *counter);
689 
690 
691 /*
692  * write_svpdu_apdu_head - 写svpdu_apdu_head到文件中
693  * @pfd: 输入参数,写地址;
694  * @head:输入参数,svpdu_apdu_head结构体;
695  * @counter: 输出参数,成功写入的字节个数;
696  *
697  * 返回当前pfd指针,写失败返回NULL
698  *
699  */
700 _my_svpdu_ioptr write_svpdu_apdu_head(_my_svpdu_ioptr pfd, struct svpdu_apdu_head *head, int *counter);
701 
702 
703 /*
704  * write_svpdu_asdu_dat92 - 写svpdu_asdu_dat92到文件中
705  * @pfd: 输入参数,写地址;
706  * @dat92:输入参数,svpdu_asdu_dat92结构体;
707  * @counter: 输出参数,成功写入的字节个数;
708  *
709  * 返回当前pfd指针,写失败返回NULL
710  *
711  */
712 _my_svpdu_ioptr write_svpdu_asdu_dat92(_my_svpdu_ioptr pfd, struct svpdu_asdu_dat92 *dat92, int *counter);
713 
714 
715 /*
716  * write_svpdu_asdu_dat91 - 写svpdu_asdu_dat91到文件中
717  * @pfd: 输入参数,写地址;
718  * @dat91:输入参数,svpdu_asdu_dat91结构体;
719  * @counter: 输出参数,成功写入的字节个数;
720  *
721  * 返回当前pfd指针,写失败返回NULL
722  *
723  */
724 _my_svpdu_ioptr write_svpdu_asdu_dat91(_my_svpdu_ioptr pfd, struct svpdu_asdu_dat91 *dat91, int *counter);
725 
726 
727 /*
728  * print_svpdu_lpdu_head - 打印数据
729  * @head: 数据包
730  *
731  */
732 void print_svpdu_lpdu_head(struct svpdu_lpdu_head * head);
733 
734 /*
735  * print_svpdu_apdu_head - 打印数据
736  * @head: 数据包
737  *
738  */
739 void print_svpdu_apdu_head(struct svpdu_apdu_head* head);
740 
741 /*
742  * print_svpdu_asdu_dat92 - 打印数据
743  * @dat92: 数据包
744  * @smpquality_enable: 是否包含质量信息
745  *
746  */
747 void print_svpdu_asdu_dat92(struct svpdu_asdu_dat92* dat92, u8 smpquality_enable);
748 
749 /*
750  * print_svpdu_asdu_dat91 - 打印数据
751  * @dat92: 数据包
752  * @smpquality_enable: 是否包含质量信息
753  *
754  */
755 void print_svpdu_asdu_dat91(struct svpdu_asdu_dat91* dat91);
756 
757 
758 #pragma pack(pop)
759 
760 #if defined (__cplusplus)
761 }
762 #endif /* defined (__cplusplus) */
763 
764 
765 #endif /* __INCLUDE_IEC61850SV_PROTOCOL_H */

 

posted on 2013-04-27 15:31  三胖他爹  阅读(5114)  评论(0编辑  收藏  举报