iec61850采样协议(91、92)解析(二)

   1 /*
   2  * iec61850采样协议(9-1、9-2)解析。
   3  *
   4  *
   5  * 本代码支持win32平台和linux平台。
   6  *
   7  * Copyright,lizhi<ibox>
   8  *
   9  * 2012-10-10 V1.0 lizhi<QQ:252240557,msn:ddgooo@hotmail.com> created
  10  *
  11  * 我曾经问过不休,你何时跟我走?可你却总是笑我,一无所有;
  12  * 我要给你我的追求,还有我的自由;可你却总是笑我,一无所有;
  13  *
  14  */
  15 
  16 
  17 /*
  18  * 头文件
  19  */
  20 #include "base_type.h"
  21 #include "base_include.h"
  22 #include "base_debug.h"
  23 #include "base_function.h"
  24 #include "base_endian.h"
  25 
  26 #include "iec61850sv_protocol.h"
  27 
  28 
  29 /*
  30  * 测试宏开关
  31  */
  32 //*
  33 #define IEC61850SV_CONSOLE_DEMO
  34 // */
  35 
  36 
  37 /*
  38  * _my_read_sv_bytes/_my_write_sv_bytes - 读取/写入并且转换sv数据。读取count个字节,fd会自加;
  39  * @pfd: 读写地址,为buffer地址;
  40  * @ptr:  读取/写入的数据;
  41  * @count: 需要读取/写入的字节个数;
  42  * @counter:  读取/写入的字节计数器;
  43  *
  44  */
  45 #define _my_read_sv_bytes(pfd, ptr, count, counter)                             \
  46         do {                                                                    \
  47                 _my_read_svpdu_bufn((pfd), (u8*)(ptr), (count));                \
  48                 (counter) += (count);                                           \
  49         } while(0)
  50 
  51 #define _my_write_sv_bytes(pfd, ptr, count, counter)                            \
  52         do {                                                                    \
  53                 _my_write_svpdu_bufn((pfd), (u8*)(ptr), (count));               \
  54                 (counter) += (count);                                           \
  55         } while(0)
  56 
  57 /*
  58  * _my_read_asn1_tag8/_my_write_asn1_tag8 - 按照asn.1规范读取/写入标志字节,fd会自加;
  59  * @pfd: 读写地址,为buffer地址;
  60  * @tag:  读取/写入的数据;
  61  * @counter:  读取/写入的字节计数器;
  62  *
  63  */
  64 #define _my_read_asn1_tag8(pfd, tag, counter)                                   \
  65         do {                                                                    \
  66                 u8 data = 0;                                                    \
  67                 _my_read_sv_bytes((pfd), &data, 1, counter);                    \
  68                 (tag) = _my_get8(&data);                                        \
  69         } while(0)
  70 #define _my_write_asn1_tag8(pfd, tag, counter)                                  \
  71         do {                                                                    \
  72                 u8 data = _my_get8(&tag);                                       \
  73                 _my_write_sv_bytes((pfd), &data, 1, counter);                   \
  74         } while(0)
  75 
  76 /*
  77  * _my_read_asn1_length/_my_write_asn1_length - 按照asn.1规范读取/写入长度,fd会自加;
  78  * @pfd: 读写地址,为buffer地址;
  79  * @len:  读取/写入的数据;
  80  * @counter:  读取/写入的字节计数器;
  81  *
  82  */
  83 #define _my_read_asn1_length(pfd, len, counter)                                 \
  84         do {                                                                    \
  85                 u8 len_first, len_bytes;                                        \
  86                 u8 datas[5];                                                    \
  87                 _my_read_sv_bytes((pfd), &len_first, 1, counter);               \
  88                 if ( len_first & 0x80 ) {                                       \
  89                         len_bytes = len_first & 0x7f;                           \
  90                         if (len_bytes == 1) {                                   \
  91                                 _my_read_sv_bytes((pfd), datas, 1, counter);    \
  92                                 (len) = *datas;                                 \
  93                         }                                                       \
  94                         else if (len_bytes == 2) {                              \
  95                                 _my_read_sv_bytes((pfd), datas, 2, counter);    \
  96                                 (len) = _my_btoh16((_my_getb16(datas)));        \
  97                         }                                                       \
  98                         else if (len_bytes == 3) {                              \
  99                                 datas[0] = 0x00;                                \
 100                                 _my_read_sv_bytes((pfd), datas+1, 3, counter);  \
 101                                 (len) = _my_btoh32((_my_getb32(datas)));        \
 102                         }                                                       \
 103                         else {                                                  \
 104                                 _my_read_sv_bytes((pfd), datas, 4, counter);    \
 105                                 (len) = _my_btoh32((_my_getb32(datas)));        \
 106                         }                                                       \
 107                 }                                                               \
 108                 else {                                                          \
 109                         (len) = len_first;                                      \
 110                 }                                                               \
 111         } while(0)
 112 #define _my_write_asn1_length(pfd, len, counter)                                \
 113         do {                                                                    \
 114                 u8 tag;                                                         \
 115                 u32 datas;                                                      \
 116                 datas = _my_htob32(((u32)(len)));                               \
 117                 if ((len) <= 0x0000007f) {                                      \
 118                         _my_write_sv_bytes((pfd), (u8*)(&datas), 1, counter);   \
 119                 }                                                               \
 120                 else if ((len) <= 0x000000ff) {                                 \
 121                         tag = (u8)0x81;                                         \
 122                         _my_write_sv_bytes((pfd), (u8*)(&tag), 1, counter);     \
 123                         _my_write_sv_bytes((pfd), (u8*)(&datas), 1, counter);   \
 124                 }                                                               \
 125                 else if ((len) <= 0x0000ffff) {                                 \
 126                         tag = (u8)0x82;                                         \
 127                         _my_write_sv_bytes((pfd), (u8*)(&tag), 1, counter);     \
 128                         _my_write_sv_bytes((pfd), (u8*)(&datas), 2, counter);   \
 129                 }                                                               \
 130                 else if ((len) <= 0x00ffffff) {                                 \
 131                         tag = (u8)0x83;                                         \
 132                         _my_write_sv_bytes((pfd), (u8*)(&tag), 1, counter);     \
 133                         _my_write_sv_bytes((pfd), (u8*)(&datas), 3, counter);   \
 134                 }                                                               \
 135                 else if ((len) <= 0xffffffff) {                                 \
 136                         tag = (u8)0x84;                                         \
 137                         _my_write_sv_bytes((pfd), (u8*)(&tag), 1, counter);     \
 138                         _my_write_sv_bytes((pfd), (u8*)(&datas), 4, counter);   \
 139                 }                                                               \
 140         } while(0)
 141 
 142 /*
 143  * _my_read_asn1_valn/_my_write_asn1_valn - 按照asn.1规范读取/写入int,fd会自加;
 144  * @pfd: 读写地址,为buffer地址;
 145  * @val:  读取/写入的数据;
 146  * @len:  数据长度;
 147  * @counter:  读取/写入的字节计数器;
 148  *
 149  */
 150 #define _my_read_asn1_valn(pfd, val, len, counter)                              \
 151         do {                                                                    \
 152                 u8 datas[5];                                                    \
 153                 if ((len) == 1) {                                               \
 154                         _my_read_sv_bytes((pfd), datas, 1, counter);            \
 155                         (val) = *datas;                                         \
 156                 }                                                               \
 157                 else if ((len) == 2) {                                          \
 158                         _my_read_sv_bytes((pfd), datas, 2, counter);            \
 159                         (val) = _my_btoh16((_my_getb16(datas)));                \
 160                 }                                                               \
 161                 else if ((len) == 3) {                                          \
 162                         datas[0] = 0x00;                                        \
 163                         _my_read_sv_bytes((pfd), datas+1, 3, counter);          \
 164                         (val) = _my_btoh32((_my_getb32(datas)));                \
 165                 }                                                               \
 166                 else if ((len) == 4) {                                          \
 167                         _my_read_sv_bytes((pfd), datas, 4, counter);            \
 168                         (val) = _my_btoh32((_my_getb32(datas)));                \
 169                 }                                                               \
 170         } while(0)
 171 #define _my_write_asn1_valn(pfd, val, len, counter)                             \
 172         do {                                                                    \
 173                 u32 datas;                                                      \
 174                 datas = _my_htob32(((u32)(val)));                               \
 175                 if ((len) == 1) {                                               \
 176                         _my_write_sv_bytes((pfd), (u8*)(&datas), 1, counter);   \
 177                 }                                                               \
 178                 else if ((len) == 2) {                                          \
 179                         _my_write_sv_bytes((pfd), (u8*)(&datas), 2, counter);   \
 180                 }                                                               \
 181                 else if ((len) == 3) {                                          \
 182                         _my_write_sv_bytes((pfd), (u8*)(&datas), 3, counter);   \
 183                 }                                                               \
 184                 else if ((len) == 4) {                                          \
 185                         _my_write_sv_bytes((pfd), (u8*)(&datas), 4, counter);   \
 186                 }                                                               \
 187         } while(0)
 188 
 189 
 190 /*
 191  * _my_read_asn1_valb/_my_write_asn1_valb - 按照asn.1规范读取/写入bytes,fd会自加;
 192  * @pfd: 读写地址,为buffer地址;
 193  * @val:  读取/写入的数据;
 194  * @len:  数据长度;
 195  * @counter:  读取/写入的字节计数器;
 196  *
 197  */
 198 #define _my_read_asn1_valb(pfd, val, len, counter)                              \
 199         _my_read_sv_bytes((pfd), (val), (len), counter);
 200 #define _my_write_asn1_valb(pfd, val, len, counter)                             \
 201         _my_write_sv_bytes((pfd), (val), (len), counter);
 202 
 203 
 204 /*
 205  * read_svpdu_lpdu_head - 取得链路层svpdu报文头部信息,没有读到的数据为其原来的值
 206  * @pfd:  输入输出参数,地址
 207  * @len: 输入参数,数据缓冲区长度;
 208  * @head: 输出参数,svpdu_lpdu_head值
 209  * @counter:  输出参数,读取的字节计数器;
 210  *
 211  * 读成功返回当前读pfd地址,否则返回NULL;
 212  *
 213  */
 214 _my_svpdu_ioptr read_svpdu_lpdu_head(_my_svpdu_ioptr pfd, int len, struct svpdu_lpdu_head *head, int *counter)
 215 {
 216         _my_svpdu_ioptr curr_pfd = pfd;
 217 
 218         _my_assert(curr_pfd && head);
 219 
 220         _my_assert( len > sizeof(struct svpdu_lpdu_head)); /* 最小长度应该大于 26 个字节,从协议计算*/
 221         _my_read_sv_bytes(curr_pfd, head->des_mac, 6, *counter);
 222         _my_read_sv_bytes(curr_pfd, head->src_mac, 6, *counter);
 223         _my_read_asn1_valn(curr_pfd, head->tpid, 2, *counter);
 224         if (head->tpid != SVPDU_LPDU_TPID_VLAN) {   /* 有的报文里面没有tpid和tci字段 不能比较 */
 225                 head->ether_type = head->tpid;
 226         }
 227         else {
 228                 _my_read_asn1_valn(curr_pfd, head->tci, 2, *counter);
 229                 _my_read_asn1_valn(curr_pfd, head->ether_type, 2, *counter);
 230         }
 231         _my_read_asn1_valn(curr_pfd, head->appid, 2, *counter);
 232         _my_read_asn1_valn(curr_pfd, head->epdu_length, 2, *counter);
 233         _my_read_asn1_valn(curr_pfd, head->reserve1, 2, *counter);
 234         _my_read_asn1_valn(curr_pfd, head->reserve2, 2, *counter);
 235 
 236         return curr_pfd;
 237 }
 238 
 239 
 240 /*
 241  * read_svpdu_apdu_head - 取得svpdu报文中apdu头部信息,没有读到的数据为其原来的值
 242  * @pfd:  输入输出参数,地址
 243  * @len: 输入参数,数据缓冲区长度;
 244  * @head: 输出参数,svpdu_lpdu_head值
 245  * @counter:  输出参数,读取的字节计数器;
 246  *
 247  * 读成功返回当前读pfd地址,否则返回NULL;
 248  *
 249  */
 250 _my_svpdu_ioptr read_svpdu_apdu_head(_my_svpdu_ioptr pfd, int len, struct svpdu_apdu_head *head, int *counter)
 251 {
 252         u8 curr_tag = 0;
 253         u32 curr_len = 0;
 254         u32 index = 0;
 255 
 256         _my_svpdu_ioptr curr_pfd =  pfd;
 257 
 258         _my_assert(curr_pfd && head);
 259 
 260         _my_read_asn1_tag8(curr_pfd, head->apdu_tag, *counter);
 261         _my_read_asn1_length(curr_pfd, head->apdu_length, *counter);
 262         if (head->apdu_tag == SVPDU_APDU_TAG_91) {
 263                 _my_read_asn1_valn(curr_pfd, head->asdu_num_value, 2, *counter);
 264                 return curr_pfd;
 265         }
 266         else if (head->apdu_tag == SVPDU_APDU_TAG_92) {
 267                 for (index = 0; index < 3; index++) { /* 最多读三遍,一般没有SVPDU_SECURITY_TAG_92 */
 268                         _my_read_asn1_tag8(curr_pfd, curr_tag, *counter);
 269                         _my_read_asn1_length(curr_pfd, curr_len, *counter);
 270                         if (curr_tag == SVPDU_ASDUNUM_TAG_92) {
 271                                 head->asdu_num_tag = curr_tag;
 272                                 head->asdu_num_length = curr_len;
 273                                 _my_read_asn1_valn(curr_pfd, head->asdu_num_value, curr_len, *counter);
 274                         }
 275                         else if (curr_tag == SVPDU_SECURITY_TAG_92) {
 276                                 head->asdu_security_tag = curr_tag;
 277                                 head->asdu_security_length = curr_len;
 278                         }
 279                         else if (curr_tag == SVPDU_SEQUENCE_TAG_92) {
 280                                 head->asdu_sequence_tag = curr_tag;
 281                                 head->asdu_sequence_length = curr_len;
 282                                 break;
 283                         }
 284                         else {
 285                                 _my_warn_info(1, "WARN: read unknown svpdu apdu head tag");
 286                                 break;
 287                         }
 288                 }
 289                 return curr_pfd;
 290         }
 291         else {
 292                 _my_warn_info(1, "WARN: not a 9-1/9-2 packet ");
 293                 return 0;
 294         }
 295 }
 296 
 297 
 298 
 299 /*
 300  * read_svpdu_asdu_dat92 - 读取9-2-asdu详细值;
 301  * @pfd:  输入输出参数,地址
 302  * @len: 输入参数,数据缓冲区长度;
 303  * @dat92: 输出参数,asdu详细值;
 304  * @smpquality_enable: 是否有质量信息;
 305  * @counter:  输出参数,读取的字节计数器;
 306  *
 307  * 读成功返回当前读pfd地址,否则返回NULL;
 308  *
 309  * 读取过程中可能会利用动态创建空间以保存svid_value、datset_value、smpdata_values、smpdata_qualitys数据;
 310  *
 311  */
 312 _my_svpdu_ioptr read_svpdu_asdu_dat92(_my_svpdu_ioptr pfd, int len, struct svpdu_asdu_dat92 *dat92, int smpquality_enable, int *counter)
 313 {
 314         _my_svpdu_ioptr curr_pfd = pfd;
 315 
 316         int begn_pos = 0;
 317         u8 curr_tag = 0;
 318         u32 curr_len = 0;
 319         u32 index = 0;
 320         u32 sizebuf = 0;
 321         u8 succ_flag = 1;
 322 
 323         _my_assert(curr_pfd && dat92);
 324 
 325         _my_read_asn1_tag8(curr_pfd, dat92->asdu_tag, *counter);
 326         _my_read_asn1_length(curr_pfd, dat92->asdu_length, *counter);
 327 
 328         begn_pos = *counter;
 329 
 330         if (dat92->asdu_tag != SVPDU_ASDU_TAG_92) {
 331                 _my_warn_info(1, "WARN: not a 9-2 asdu packet ");
 332                 return 0;
 333         }
 334 
 335         while ((u32)((*counter) - begn_pos) <  dat92->asdu_length) {
 336                 _my_read_asn1_tag8(curr_pfd, curr_tag, *counter);
 337                 _my_read_asn1_length(curr_pfd, curr_len, *counter);
 338                 switch (curr_tag) {
 339                 case SVPDU_ASDU_SVID_TAG_92 :
 340                         dat92->svid_tag = curr_tag;
 341                         dat92->svid_length = curr_len;
 342                         if (dat92->svid_value != NULL) {
 343                                 _my_buf_free(dat92->svid_value);
 344                                 dat92->svid_value = NULL;
 345                         }
 346                         if (curr_len > 0) {
 347                                 sizebuf = curr_len + 1;
 348                                 dat92->svid_value = _my_buf_malloc(sizebuf);
 349                                 memset(dat92->svid_value, 0, sizebuf);
 350                                 _my_read_asn1_valb(curr_pfd, dat92->svid_value, curr_len, *counter);
 351                         }
 352                         break;
 353                 case SVPDU_ASDU_DATSET_TAG_92 :
 354                         dat92->datset_tag = curr_tag;
 355                         dat92->datset_length = curr_len;
 356                         if (dat92->datset_value != NULL) {
 357                                 _my_buf_free(dat92->datset_value);
 358                                 dat92->datset_value = NULL;
 359                         }
 360                         if (curr_len > 0) {
 361                                 sizebuf = curr_len + 1;
 362                                 dat92->datset_value = _my_buf_malloc(sizebuf);
 363                                 memset(dat92->datset_value, 0, sizebuf);
 364                                 _my_read_asn1_valb(curr_pfd, dat92->datset_value, curr_len, *counter);
 365                         }
 366                         break;
 367                 case SVPDU_ASDU_SMPCNT_TAG_92 :
 368                         dat92->smpcnt_tag = curr_tag;
 369                         dat92->smpcnt_length = curr_len;
 370                         _my_read_asn1_valn(curr_pfd, dat92->smpcnt_value, curr_len, *counter);
 371                         break;
 372                 case SVPDU_ASDU_CONFREV_TAG_92 :
 373                         dat92->confrev_tag = curr_tag;
 374                         dat92->confrev_length = curr_len;
 375                         _my_read_asn1_valn(curr_pfd, dat92->confrev_value, curr_len, *counter);
 376                         break;
 377                 case SVPDU_ASDU_REFRTM_TAG_92 :
 378                         dat92->refrtm_tag =         curr_tag;
 379                         dat92->refrtm_length = curr_len;
 380                         _my_read_asn1_valn(curr_pfd, dat92->refrtm_value, curr_len, *counter);
 381                         break;
 382                 case SVPDU_ASDU_SMPSYNCH_TAG_92 :
 383                         dat92->smpsynch_tag = curr_tag;
 384                         dat92->smpsynch_length = curr_len;
 385                         _my_read_asn1_valn(curr_pfd, dat92->smpsynch_value, curr_len, *counter);
 386                         break;
 387                 case SVPDU_ASDU_SMPRATE_TAG_92 :
 388                         dat92->smprate_tag = curr_tag;
 389                         dat92->smprate_length = curr_len;
 390                         _my_read_asn1_valn(curr_pfd, dat92->smprate_value, curr_len, *counter);
 391                         break;
 392                 case SVPDU_ASDU_SMPDATA_TAG_92 :
 393                         dat92->smpdata_tag = curr_tag;
 394                         dat92->smpdata_length = curr_len;
 395                         dat92->smpdata_portnum = (u16)(curr_len / (smpquality_enable ? 8 : 4));
 396                         if (dat92->smpdata_values != NULL) {
 397                                 _my_buf_free(dat92->smpdata_values);
 398                                 dat92->smpdata_values = NULL;
 399                         }
 400                         if (dat92->smpdata_qualitys != NULL) {
 401                                 _my_buf_free(dat92->smpdata_qualitys);
 402                                 dat92->smpdata_qualitys = NULL;
 403                         }
 404                         if (dat92->smpdata_portnum > 0) {
 405                                 sizebuf = dat92->smpdata_portnum * sizeof(s32);
 406                                 dat92->smpdata_values = _my_buf_malloc(sizebuf);
 407                                 memset(dat92->smpdata_values, 0, sizebuf);
 408                                 dat92->smpdata_qualitys = _my_buf_malloc(sizebuf);
 409                                 memset(dat92->smpdata_qualitys, 0, sizebuf);
 410                         }
 411                         for (index = 0; (index < dat92->smpdata_portnum); index++) {
 412                                 _my_read_asn1_valn(curr_pfd, dat92->smpdata_values[index], 4, *counter);
 413                                 _my_read_asn1_valn(curr_pfd, dat92->smpdata_qualitys[index], 4, *counter);
 414                         }
 415                         break;
 416                 default:
 417                         _my_warn_info(1, "WARN: not a 9-1/9-2 asdu item packet ");
 418                         succ_flag = 0;
 419                         break;
 420                 }
 421         }
 422 
 423         return succ_flag ? curr_pfd : 0;
 424 }
 425 
 426 
 427 /*
 428  * init_svpdu_asdu_dat92 - 初始化Dat92结构体;
 429  * @dat92: 输入输出参数,asdu详细值;
 430  * @setdefaultval: 参数是否赋默认值;
 431  *
 432  * 初始化成功返回当前dat92结构体地址,否则返回NULL;
 433  *
 434  */
 435 struct svpdu_asdu_dat92 * init_svpdu_asdu_dat92(struct svpdu_asdu_dat92 *dat92, int setdefaultval)
 436 {
 437         struct svpdu_asdu_dat92 *dat = dat92;
 438 
 439         if (dat == NULL) {
 440                 dat = (struct svpdu_asdu_dat92 *)_my_buf_malloc(sizeof(struct svpdu_asdu_dat92));
 441                 dat->svid_value = NULL;
 442                 dat->datset_value = NULL;
 443                 dat->smpdata_values = NULL;
 444                 dat->smpdata_qualitys = NULL;
 445         }
 446 
 447         memset(dat, 0, sizeof(struct svpdu_asdu_dat92));
 448         if (dat->svid_value != NULL) {
 449                 _my_buf_free(dat->svid_value);
 450                 dat->svid_value = NULL;
 451         }
 452         if (dat->datset_value != NULL) {
 453                 _my_buf_free(dat->datset_value);
 454                 dat->datset_value = NULL;
 455         }
 456         if (dat->smpdata_values != NULL) {
 457                 _my_buf_free(dat->smpdata_values);
 458                 dat->smpdata_values = NULL;
 459         }
 460         if (dat->smpdata_qualitys != NULL) {
 461                 _my_buf_free(dat->smpdata_qualitys);
 462                 dat->smpdata_qualitys = NULL;
 463         }
 464 
 465         if (setdefaultval) {
 466                 dat->asdu_tag = SVPDU_ASDU_TAG_92;
 467                 dat->svid_tag = SVPDU_ASDU_SVID_TAG_92;
 468                 dat->datset_tag = SVPDU_ASDU_DATSET_TAG_92;
 469                 dat->smpcnt_tag = SVPDU_ASDU_SMPCNT_TAG_92;
 470                 dat->confrev_tag = SVPDU_ASDU_CONFREV_TAG_92;
 471                 dat->refrtm_tag = SVPDU_ASDU_REFRTM_TAG_92;
 472                 dat->smpsynch_tag = SVPDU_ASDU_SMPSYNCH_TAG_92;
 473                 dat->smprate_tag = SVPDU_ASDU_SMPRATE_TAG_92;
 474                 dat->smpdata_tag = SVPDU_ASDU_SMPDATA_TAG_92;
 475         }
 476 
 477         return dat;
 478 }
 479 
 480 /*
 481  * free_svpdu_asdu_dat92 - 释放Dat92结构体;
 482  * @dat92: 输入输出参数,asdu详细值;
 483  *
 484  * 初始化成功返回返回NULL,否则返回当前dat92结构体地址;
 485  *
 486  */
 487 struct svpdu_asdu_dat92 * free_svpdu_asdu_dat92(struct svpdu_asdu_dat92 *dat92)
 488 {
 489         struct svpdu_asdu_dat92 *dat = dat92;
 490 
 491         if (dat != NULL) {
 492                 if (dat->svid_value != NULL) {
 493                         _my_buf_free(dat->svid_value);
 494                         dat->svid_value = NULL;
 495                 }
 496                 if (dat->datset_value != NULL) {
 497                         _my_buf_free(dat->datset_value);
 498                         dat->datset_value = NULL;
 499                 }
 500                 if (dat->smpdata_values != NULL) {
 501                         _my_buf_free(dat->smpdata_values);
 502                         dat->smpdata_values = NULL;
 503                 }
 504                 if (dat->smpdata_qualitys != NULL) {
 505                         _my_buf_free(dat->smpdata_qualitys);
 506                         dat->smpdata_qualitys = NULL;
 507                 }
 508                 _my_buf_free(dat);
 509                 dat = NULL;
 510         }
 511 
 512         return dat;
 513 }
 514 
 515 
 516 
 517 
 518 /*
 519  * read_svpdu_asdu_dat91 - 读取9-1-asdu详细值;
 520  * @pfd:  输入输出参数,地址
 521  * @len: 输入参数,数据缓冲区长度;
 522  * @dat91: 输出参数,asdu详细值;
 523  * @counter:  输出参数,读取的字节计数器;
 524  *
 525  * 读成功返回当前读pfd地址,否则返回NULL;
 526  *
 527  * 读取过程中可能会利用动态创建空间以保存smpdata_values数据;
 528  *
 529  */
 530 _my_svpdu_ioptr read_svpdu_asdu_dat91(_my_svpdu_ioptr pfd, int len, struct svpdu_asdu_dat91 *dat91, int *counter)
 531 {
 532         _my_svpdu_ioptr curr_pfd = pfd;
 533 
 534         u32 index = 0;
 535         u32 sizebuf = 0;
 536 
 537         _my_assert(curr_pfd && dat91);
 538 
 539         _my_read_asn1_valn(curr_pfd, dat91->asdu_length, 2, *counter);
 540 
 541         _my_assert(dat91->smpdata_portnum >= 20);
 542 
 543         _my_read_asn1_valn(curr_pfd, dat91->ln_name, 1, *counter);
 544         _my_read_asn1_valn(curr_pfd, dat91->dataset_name, 1, *counter);
 545         _my_read_asn1_valn(curr_pfd, dat91->ld_name, 2, *counter);
 546         _my_read_asn1_valn(curr_pfd, dat91->i_pp, 2, *counter);
 547         _my_read_asn1_valn(curr_pfd, dat91->i_p0, 2, *counter);
 548         _my_read_asn1_valn(curr_pfd, dat91->u_pp, 2, *counter);
 549         _my_read_asn1_valn(curr_pfd, dat91->t_delay, 2, *counter);
 550 
 551         dat91->smpdata_portnum = (dat91->asdu_length - 20) / 2;
 552 
 553         _my_assert(dat91->smpdata_portnum >= 0);
 554 
 555         if (dat91->smpdata_values != NULL) {
 556                 _my_buf_free(dat91->smpdata_values);
 557                 dat91->smpdata_values = NULL;
 558         }
 559         if (dat91->smpdata_portnum > 0) {
 560                 sizebuf = dat91->smpdata_portnum * sizeof(s16);
 561                 dat91->smpdata_values = _my_buf_malloc(sizebuf);
 562                 memset(dat91->smpdata_values, 0, sizebuf);
 563         }
 564 
 565         for (index=0; index<dat91->smpdata_portnum; index++) {
 566                 _my_read_asn1_valn(curr_pfd, dat91->smpdata_values[index], 2, *counter);
 567         }
 568 
 569         _my_read_asn1_valn(curr_pfd, dat91->status_word1, 2, *counter);
 570         _my_read_asn1_valn(curr_pfd, dat91->status_word2, 2, *counter);
 571         _my_read_asn1_valn(curr_pfd, dat91->smp_cnt, 2, *counter);
 572         _my_read_asn1_valn(curr_pfd, dat91->smp_rate, 1, *counter);
 573         _my_read_asn1_valn(curr_pfd, dat91->version, 1, *counter);
 574 
 575         return curr_pfd;
 576 }
 577 
 578 /*
 579  * init_svpdu_asdu_dat91 - 初始化Dat91结构体;
 580  * @dat92: 输入输出参数,asdu详细值;
 581  *
 582  * 初始化成功返回当前dat91结构体地址,否则返回NULL;
 583  *
 584  */
 585 struct svpdu_asdu_dat91 * init_svpdu_asdu_dat91(struct svpdu_asdu_dat91 *dat91)
 586 {
 587         struct svpdu_asdu_dat91 *dat = dat91;
 588 
 589         if (dat == NULL) {
 590                 dat = (struct svpdu_asdu_dat91 *)_my_buf_malloc(sizeof(struct svpdu_asdu_dat91));
 591                 dat->smpdata_values = NULL;
 592         }
 593 
 594         memset(dat, 0, sizeof(struct svpdu_asdu_dat91));
 595         if (dat->smpdata_values != NULL) {
 596                 _my_buf_free(dat->smpdata_values);
 597                 dat->smpdata_values = NULL;
 598         }
 599 
 600         return dat;
 601 }
 602 
 603 /*
 604  * free_svpdu_asdu_dat91 - 释放Dat91结构体;
 605  * @dat91: 输入输出参数,asdu详细值;
 606  *
 607  * 初始化成功返回返回NULL,否则返回当前dat91结构体地址;
 608  *
 609  */
 610 struct svpdu_asdu_dat91 * free_svpdu_asdu_dat91(struct svpdu_asdu_dat91 *dat91)
 611 {
 612         struct svpdu_asdu_dat91 *dat = dat91;
 613 
 614         if (dat != NULL) {
 615                 if (dat->smpdata_values != NULL) {
 616                         _my_buf_free(dat->smpdata_values);
 617                         dat->smpdata_values = NULL;
 618                 }
 619                 _my_buf_free(dat);
 620                 dat = NULL;
 621         }
 622 
 623         return dat;
 624 }
 625 
 626 
 627 
 628 
 629 /*
 630  * write_svpdu_lpdu_head - 写svpdu_lpdu_head到文件中
 631  * @pfd: 输入参数,写地址;
 632  * @head:输入参数,svpdu_lpdu_head结构体;
 633  * @counter: 输出参数,成功写入的字节个数;
 634  *
 635  * 返回当前pfd指针,写失败返回NULL
 636  *
 637  */
 638 _my_svpdu_ioptr write_svpdu_lpdu_head(_my_svpdu_ioptr pfd, struct svpdu_lpdu_head *head, int *counter)
 639 {
 640         _my_svpdu_ioptr curr_pfd = pfd;
 641 
 642         _my_assert(curr_pfd && head);
 643 
 644         _my_write_sv_bytes(curr_pfd, head->des_mac, 6, *counter);
 645         _my_write_sv_bytes(curr_pfd, head->src_mac, 6, *counter);
 646         _my_write_asn1_valn(curr_pfd, (u32)(head->tpid), 2, *counter);
 647         _my_write_asn1_valn(curr_pfd, (u32)(head->tci), 2, *counter);
 648         _my_write_asn1_valn(curr_pfd, (u32)(head->ether_type), 2, *counter);
 649         _my_write_asn1_valn(curr_pfd, (u32)(head->appid), 2, *counter);
 650         _my_write_asn1_valn(curr_pfd, (u32)(head->epdu_length), 2, *counter);
 651         _my_write_asn1_valn(curr_pfd, (u32)(head->reserve1), 2, *counter);
 652         _my_write_asn1_valn(curr_pfd, (u32)(head->reserve1), 2, *counter);
 653 
 654         return curr_pfd;
 655 }
 656 
 657 
 658 
 659 /*
 660  * write_svpdu_apdu_head - 写svpdu_apdu_head到文件中
 661  * @pfd: 输入参数,写地址;
 662  * @head:输入参数,svpdu_apdu_head结构体;
 663  * @counter: 输出参数,成功写入的字节个数;
 664  *
 665  * 返回当前pfd指针,写失败返回NULL
 666  *
 667  */
 668 _my_svpdu_ioptr write_svpdu_apdu_head(_my_svpdu_ioptr pfd, struct svpdu_apdu_head *head, int *counter)
 669 {
 670         _my_svpdu_ioptr curr_pfd = pfd;
 671 
 672         _my_assert(curr_pfd && head);
 673 
 674         _my_write_asn1_tag8(curr_pfd, head->apdu_tag, *counter);
 675         _my_write_asn1_length(curr_pfd, head->apdu_length, *counter);
 676 
 677         if (head->apdu_tag == SVPDU_APDU_TAG_92){
 678                 _my_write_asn1_tag8(curr_pfd, head->asdu_num_tag, *counter);
 679                 _my_write_asn1_length(curr_pfd, head->asdu_num_length, *counter);
 680         }
 681         _my_write_asn1_valn(curr_pfd, (u32)(head->asdu_num_value), 2, *counter);
 682 
 683         if (head->apdu_tag == SVPDU_APDU_TAG_92){
 684                 if (head->asdu_security_tag != 0x00) {
 685                         _my_write_asn1_tag8(curr_pfd, head->asdu_security_tag, *counter);
 686                         _my_write_asn1_length(curr_pfd, head->asdu_security_length, *counter);
 687                 }
 688                 if (head->asdu_sequence_tag != 0x00) {
 689                         _my_write_asn1_tag8(curr_pfd, head->asdu_sequence_tag, *counter);
 690                         _my_write_asn1_length(curr_pfd, head->asdu_sequence_length, *counter);
 691                 }
 692         }
 693 
 694         return curr_pfd;
 695 }
 696 
 697 
 698 /*
 699  * write_svpdu_asdu_dat92 - 写svpdu_asdu_dat92到文件中
 700  * @pfd: 输入参数,写地址;
 701  * @dat92:输入参数,svpdu_asdu_dat92结构体;
 702  * @counter: 输出参数,成功写入的字节个数;
 703  *
 704  * 返回当前pfd指针,写失败返回NULL
 705  *
 706  */
 707 _my_svpdu_ioptr write_svpdu_asdu_dat92(_my_svpdu_ioptr pfd, struct svpdu_asdu_dat92 *dat92, int *counter)
 708 {
 709          _my_svpdu_ioptr curr_pfd = pfd;
 710 
 711          u32 index = 0;
 712 
 713         _my_assert(curr_pfd && dat92);
 714 
 715         _my_write_asn1_tag8(curr_pfd, dat92->asdu_tag, *counter);
 716         _my_write_asn1_length(curr_pfd, dat92->asdu_length, *counter);
 717 
 718         if (dat92->svid_tag == SVPDU_ASDU_SVID_TAG_92) {
 719                 _my_write_asn1_tag8(curr_pfd, dat92->svid_tag, *counter);
 720                 _my_write_asn1_length(curr_pfd, dat92->svid_length, *counter);
 721                 _my_write_asn1_valb(curr_pfd, dat92->svid_value, dat92->svid_length, *counter);
 722         }
 723         if (dat92->datset_tag == SVPDU_ASDU_DATSET_TAG_92) {
 724                 _my_write_asn1_tag8(curr_pfd, dat92->datset_tag, *counter);
 725                 _my_write_asn1_length(curr_pfd, dat92->datset_length, *counter);
 726                 _my_write_asn1_valb(curr_pfd, dat92->datset_value, dat92->datset_length, *counter);
 727         }
 728         if (dat92->smpcnt_tag == SVPDU_ASDU_SMPCNT_TAG_92) {
 729                 _my_write_asn1_tag8(curr_pfd, dat92->smpcnt_tag, *counter);
 730                 _my_write_asn1_length(curr_pfd, dat92->smpcnt_length, *counter);
 731                 _my_write_asn1_valn(curr_pfd, dat92->smpcnt_value, dat92->smpcnt_length, *counter);
 732         }
 733         if (dat92->confrev_tag == SVPDU_ASDU_CONFREV_TAG_92) {
 734                 _my_write_asn1_tag8(curr_pfd, dat92->confrev_tag, *counter);
 735                 _my_write_asn1_length(curr_pfd, dat92->confrev_length, *counter);
 736                 _my_write_asn1_valn(curr_pfd, dat92->confrev_value, dat92->confrev_length, *counter);
 737         }
 738         if (dat92->refrtm_tag == SVPDU_ASDU_REFRTM_TAG_92) {
 739                 _my_write_asn1_tag8(curr_pfd, dat92->refrtm_tag, *counter);
 740                 _my_write_asn1_length(curr_pfd, dat92->refrtm_length, *counter);
 741                 _my_write_asn1_valn(curr_pfd, dat92->refrtm_value, dat92->refrtm_length, *counter);
 742         }
 743         if (dat92->smpsynch_tag == SVPDU_ASDU_SMPSYNCH_TAG_92) {
 744                 _my_write_asn1_tag8(curr_pfd, dat92->refrtm_tag, *counter);
 745                 _my_write_asn1_length(curr_pfd, dat92->smpsynch_length, *counter);
 746                 _my_write_asn1_valn(curr_pfd, dat92->smpsynch_value, dat92->smpsynch_length, *counter);
 747         }
 748         if (dat92->smprate_tag == SVPDU_ASDU_SMPRATE_TAG_92) {
 749                 _my_write_asn1_tag8(curr_pfd, dat92->smprate_tag, *counter);
 750                 _my_write_asn1_length(curr_pfd, dat92->smprate_length, *counter);
 751                 _my_write_asn1_valn(curr_pfd, dat92->smprate_value, dat92->smprate_length, *counter);
 752         }
 753         if (dat92->smpdata_tag == SVPDU_ASDU_SMPDATA_TAG_92) {
 754                 _my_write_asn1_tag8(curr_pfd, dat92->smpdata_tag, *counter);
 755                 _my_write_asn1_length(curr_pfd, dat92->smpdata_length, *counter);
 756                 for (index = 0; (index < dat92->smpdata_portnum); index++) {
 757                         _my_write_asn1_valn(curr_pfd, dat92->smpdata_values[index], 4, *counter);
 758                         _my_write_asn1_valn(curr_pfd, dat92->smpdata_qualitys[index], 4, *counter);
 759                 }
 760         }
 761 
 762         return curr_pfd;
 763 }
 764 
 765 
 766 /*
 767  * write_svpdu_asdu_dat91 - 写svpdu_asdu_dat91到文件中
 768  * @pfd: 输入参数,写地址;
 769  * @dat91:输入参数,svpdu_asdu_dat91结构体;
 770  * @counter: 输出参数,成功写入的字节个数;
 771  *
 772  * 返回当前pfd指针,写失败返回NULL
 773  *
 774  */
 775 _my_svpdu_ioptr write_svpdu_asdu_dat91(_my_svpdu_ioptr pfd, struct svpdu_asdu_dat91 *dat91, int *counter)
 776 {
 777          _my_svpdu_ioptr curr_pfd = pfd;
 778 
 779          u32 index = 0;
 780 
 781         _my_assert(curr_pfd && dat91);
 782 
 783         _my_write_asn1_valn(curr_pfd, dat91->asdu_length, 2, *counter);
 784         _my_write_asn1_valn(curr_pfd, dat91->ln_name, 1, *counter);
 785         _my_write_asn1_valn(curr_pfd, dat91->dataset_name, 1, *counter);
 786         _my_write_asn1_valn(curr_pfd, dat91->ld_name, 2, *counter);
 787         _my_write_asn1_valn(curr_pfd, dat91->i_pp, 2, *counter);
 788         _my_write_asn1_valn(curr_pfd, dat91->i_p0, 2, *counter);
 789         _my_write_asn1_valn(curr_pfd, dat91->u_pp, 2, *counter);
 790         _my_write_asn1_valn(curr_pfd, dat91->t_delay, 2, *counter);
 791         for (index = 0; (index < dat91->smpdata_portnum); index++) {
 792                 _my_write_asn1_valn(curr_pfd, dat91->smpdata_values[index], 2, *counter);
 793         }
 794         _my_write_asn1_valn(curr_pfd, dat91->status_word1, 2, *counter);
 795         _my_write_asn1_valn(curr_pfd, dat91->status_word2, 2, *counter);
 796         _my_write_asn1_valn(curr_pfd, dat91->smp_cnt, 2, *counter);
 797         _my_write_asn1_valn(curr_pfd, dat91->smp_rate, 1, *counter);
 798         _my_write_asn1_valn(curr_pfd, dat91->version, 1, *counter);
 799 
 800         return curr_pfd;
 801 }
 802 
 803 /*
 804  * print_svpdu_lpdu_head - 打印数据
 805  * @head: 数据包
 806  *
 807  */
 808 void print_svpdu_lpdu_head(struct svpdu_lpdu_head * head) {
 809         if ( head ) {
 810                 _my_printf("========= svpdu_lpdu_head ============\n");
 811                 _my_printf("des_mac:%02X:%02X:%02X:%02X:%02X:%02X\n",
 812                         head->des_mac[0], head->des_mac[1], head->des_mac[2],
 813                         head->des_mac[3], head->des_mac[4], head->des_mac[5]);
 814                 _my_printf("src_mac:%02X:%02X:%02X:%02X:%02X:%02X\n",
 815                         head->src_mac[0], head->src_mac[1], head->src_mac[2],
 816                         head->src_mac[3], head->src_mac[4], head->src_mac[5]);
 817                 _my_printf("tpid:%u [0x%04X]\n", head->tpid, head->tpid);
 818                 _my_printf("tci:%u [0x%04X]\n", head->tci, head->tci);
 819                 _my_printf("ether_type:%u [0x%04X]\n", head->ether_type, head->ether_type);
 820                 _my_printf("appid:%u [0x%04X]\n", head->appid, head->appid);
 821                 _my_printf("epdu_length:%u [0x%04X]\n", head->epdu_length, head->epdu_length);
 822                 _my_printf("reserve1:%u [0x%04X]\n", head->reserve1, head->reserve1);
 823                 _my_printf("reserve2:%u [0x%04X]\n", head->reserve2, head->reserve2);
 824                 _my_printf("=====================\n");
 825         }
 826 }
 827 
 828 /*
 829  * print_svpdu_apdu_head - 打印数据
 830  * @head: 数据包
 831  *
 832  */
 833 void print_svpdu_apdu_head(struct svpdu_apdu_head* head) {
 834         if ( head ) {
 835                 _my_printf("========= svpdu_apdu_head ============\n");
 836                 _my_printf("apdu_tag:%u [0x%02X]\n", head->apdu_tag, head->apdu_tag);
 837                 _my_printf("apdu_length:%u [0x%08X]\n", head->apdu_length, head->apdu_length);
 838                 _my_printf("asdu_num_tag:%u [0x%02X]\n", head->asdu_num_tag, head->asdu_num_tag);
 839                 _my_printf("asdu_num_length:%u [0x%08X]\n", head->asdu_num_length, head->asdu_num_length);
 840                 _my_printf("asdu_num_value:%u [0x%04X]\n", head->asdu_num_value, head->asdu_num_value);
 841                 _my_printf("asdu_security_tag:%u [0x%02X]\n", head->asdu_security_tag, head->asdu_security_tag);
 842                 _my_printf("asdu_security_length:%u [0x%08X]\n", head->asdu_security_length, head->asdu_security_length);
 843                 _my_printf("asdu_sequence_tag:%u [0x%02X]\n", head->asdu_sequence_tag, head->asdu_sequence_tag);
 844                 _my_printf("asdu_sequence_length:%u [0x%08X]\n", head->asdu_sequence_length, head->asdu_sequence_length);
 845                 _my_printf("=====================\n");
 846         }
 847 }
 848 
 849 /*
 850  * print_svpdu_asdu_dat92 - 打印数据
 851  * @dat92: 数据包
 852  * @smpquality_enable: 是否包含质量信息
 853  *
 854  */
 855 void print_svpdu_asdu_dat92(struct svpdu_asdu_dat92* dat92, u8 smpquality_enable){
 856         u32 index = 0;
 857         if ( dat92 ) {
 858                 _my_printf("========= svpdu_asdu_dat92 ============\n");
 859                 _my_printf("asdu_tag:%u [0x%02X]\n", dat92->asdu_tag, dat92->asdu_tag);
 860                 _my_printf("asdu_length:%u [0x%08X]\n", dat92->asdu_length, dat92->asdu_length);
 861                 _my_printf("svid_tag:%u [0x%02X]\n", dat92->svid_tag, dat92->svid_tag);
 862                 _my_printf("svid_length:%u [0x%08X]\n", dat92->svid_length, dat92->svid_length);
 863                 _my_printf("svid_value:\n");
 864                 for (index = 0; index < dat92->svid_length; index++) {
 865                         if ((index % 16) == 0) {
 866                                 _my_printf("\n");
 867                         }
 868                         _my_printf("%02X ", dat92->svid_value[index]);
 869                 }
 870                 _my_printf("\n");
 871                 _my_printf("datset_tag:%u [0x%02X]\n", dat92->datset_tag, dat92->datset_tag);
 872                 _my_printf("datset_length:%u [0x%08X]\n", dat92->datset_length, dat92->datset_length);
 873                 _my_printf("datset_value:\n");
 874                 for (index = 0; index < dat92->datset_length; index++) {
 875                         if ((index % 16) == 0) {
 876                                 _my_printf("\n");
 877                         }
 878                         _my_printf("%02X ", dat92->datset_value[index]);
 879                 }
 880                 _my_printf("\n");
 881                 _my_printf("smpcnt_tag:%u [0x%02X]\n", dat92->smpcnt_tag, dat92->smpcnt_tag);
 882                 _my_printf("smpcnt_length:%u [0x%08X]\n", dat92->smpcnt_length, dat92->smpcnt_length);
 883                 _my_printf("smpcnt_value:%u [0x%04X]\n", dat92->smpcnt_value, dat92->smpcnt_value);
 884                 _my_printf("confrev_tag:%u [0x%02X]\n", dat92->confrev_tag, dat92->confrev_tag);
 885                 _my_printf("confrev_length:%u [0x%08X]\n", dat92->confrev_length, dat92->confrev_length);
 886                 _my_printf("confrev_value:%u [0x%08X]\n", dat92->confrev_value, dat92->confrev_value);
 887                 _my_printf("refrtm_tag:%u [0x%02X]\n", dat92->refrtm_tag, dat92->refrtm_tag);
 888                 _my_printf("refrtm_length:%u [0x%08X]\n", dat92->refrtm_length, dat92->refrtm_length);
 889                 _my_printf("refrtm_value:%u [0x%08X]\n", dat92->refrtm_value, dat92->refrtm_value);
 890                 _my_printf("smpsynch_tag:%u [0x%02X]\n", dat92->smpsynch_tag, dat92->smpsynch_tag);
 891                 _my_printf("smpsynch_length:%u [0x%08X]\n", dat92->smpsynch_length, dat92->smpsynch_length);
 892                 _my_printf("smpsynch_tag:%u [0x%02X]\n", dat92->smpsynch_tag, dat92->smpsynch_tag);
 893                 _my_printf("smprate_tag:%u [0x%02X]\n", dat92->smprate_tag, dat92->smprate_tag);
 894                 _my_printf("smprate_length:%u [0x%08X]\n", dat92->smprate_length, dat92->smprate_length);
 895                 _my_printf("smprate_value:%u [0x%04X]\n", dat92->smprate_value, dat92->smprate_value);
 896                 _my_printf("smpdata_tag:%u [0x%02X]\n", dat92->smpdata_tag, dat92->smpdata_tag);
 897                 _my_printf("smpdata_length:%u [0x%08X]\n", dat92->smpdata_length, dat92->smpdata_length);
 898                 _my_printf("smpdata_portnum:%u [0x%04X]\n", dat92->smpdata_portnum, dat92->smpdata_portnum);
 899                 _my_printf("smpdata_values:\n");
 900                 for (index = 0; index < dat92->smpdata_portnum; index++) {
 901                         if ((index % 8) == 0) {
 902                                 _my_printf("\n");
 903                         }
 904                         _my_printf("%d[%08X] %lf ",
 905                                 dat92->smpdata_values[index],
 906                                 dat92->smpdata_values[index],
 907                                 (double)(dat92->smpdata_values[index]));
 908                 }
 909                 _my_printf("\n");
 910                 if (smpquality_enable) {
 911                         _my_printf("smpdata_qualitys:\n");
 912                         for (index = 0; index < dat92->smpdata_portnum; index++) {
 913                                 if ((index % 8) == 0) {
 914                                         _my_printf("\n");
 915                                 }
 916                                 _my_printf("%d[%08X] ", dat92->smpdata_qualitys[index], dat92->smpdata_qualitys[index]);
 917                         }
 918                         _my_printf("\n");
 919                 }
 920                 _my_printf("=====================\n");
 921         }
 922 }
 923 
 924 
 925 /*
 926  * print_svpdu_asdu_dat91 - 打印数据
 927  * @dat92: 数据包
 928  * @smpquality_enable: 是否包含质量信息
 929  *
 930  */
 931 void print_svpdu_asdu_dat91(struct svpdu_asdu_dat91* dat91){
 932         u32 index = 0;
 933         if ( dat91 ) {
 934                 _my_printf("========= svpdu_asdu_dat91 ============\n");
 935                 _my_printf("asdu_length:%u [0x%04X]\n", dat91->asdu_length, dat91->asdu_length);
 936                 _my_printf("ln_name:%u [0x%02X]\n", dat91->ln_name, dat91->ln_name);
 937                 _my_printf("dataset_name:%u [0x%04X]\n", dat91->dataset_name, dat91->dataset_name);
 938                 _my_printf("ld_name:%u [0x%04X]\n", dat91->ld_name, dat91->ld_name);
 939                 _my_printf("i_pp:%u [0x%04X]\n", dat91->i_pp, dat91->i_pp);
 940                 _my_printf("i_p0:%u [0x%04X]\n", dat91->i_p0, dat91->i_p0);
 941                 _my_printf("u_pp:%u [0x%04X]\n", dat91->u_pp, dat91->u_pp);
 942                 _my_printf("t_delay:%u [0x%04X]\n", dat91->t_delay, dat91->t_delay);
 943                 _my_printf("smpdata_portnum:%u [0x%04X]\n", dat91->smpdata_portnum, dat91->smpdata_portnum);
 944                 _my_printf("smpdata_values:\n");
 945                 for (index = 0; index < dat91->smpdata_portnum; index++) {
 946                         if ((index % 6) == 0) {
 947                                 _my_printf("\n");
 948                         }
 949                         _my_printf("%d[%04X] ",
 950                                 dat91->smpdata_values[index],
 951                                 dat91->smpdata_values[index]);
 952                 }
 953                 _my_printf("\n");
 954                 _my_printf("status_word1:%u [0x%04X]\n", dat91->status_word1, dat91->status_word1);
 955                 _my_printf("status_word2:%u [0x%04X]\n", dat91->status_word2, dat91->status_word2);
 956                 _my_printf("smp_cnt:%u [0x%04X]\n", dat91->smp_cnt, dat91->smp_cnt);
 957                 _my_printf("smp_rate:%u [0x%02X]\n", dat91->smp_rate, dat91->smp_rate);
 958                 _my_printf("version:%u [0x%02X]\n", dat91->version, dat91->version);
 959                 _my_printf("=====================\n");
 960         }
 961 }
 962 
 963 
 964 #ifdef IEC61850SV_CONSOLE_DEMO
 965 
 966 #include "pcap_protocol.h"
 967 
 968 /*
 969  * _my_pcap_openrb/_my_pcap_openwb/_my_pcap_openab/_my_pcap_close
 970  *              - 可以根据需要改写该接口,如重定义为网口的recv\send、串口r\w等
 971  * @pfd:  文件地址、缓冲区地址、或者socket地址等
 972  * @str:  文件路径或者联机ip或者串口地址或者共享内存名称
 973  *
 974  */
 975 #ifdef PCAP_IOFILE
 976 #define _my_pcap_openrb(str)    (open((str), O_RDONLY | O_BINARY, S_IWRITE | S_IREAD))
 977 #define _my_pcap_openwb(str)    (open((str), O_CREAT | O_RDWR | O_BINARY, S_IWRITE | S_IREAD))
 978 #define _my_pcap_openab(str)    (open((str), O_CREAT | O_APPEND | O_RDWR | O_BINARY, S_IWRITE | S_IREAD))
 979 #define _my_pcap_close(pfd)     (close(pfd))
 980 #else /* 定义其他的io*/
 981 #endif
 982 
 983 /*
 984  * i92p_test_demo1 - 测试函数
 985  * @pcap_pathname:  pcap文件路径
 986  * @packet_pathname:  pcaket文件路径
 987  *
 988  */
 989 void i92p_test_demo1(const char* pcap_pathname, u8 smpquality_enable) {
 990         int pckt_count = 0;
 991         int read_count = 0;
 992         u8* ppd = 0;
 993         struct pcap_file_head pfh;
 994         struct pcap_packet_head pph;
 995 
 996         _my_svpdu_ioptr curr_pdf = 0;
 997         int bgn_pos = 0;
 998         int end_pos = 0;
 999 
1000         int index = 0;
1001         int count = 0;
1002 
1003         char chget;
1004 
1005         _my_pcap_ioptr fdpcap = 0;
1006 
1007         struct svpdu_lpdu_head lpdu_head;
1008         struct svpdu_apdu_head apdu_head;
1009         struct svpdu_asdu_dat92 asdu_dat92;
1010 
1011         fdpcap = _my_pcap_openrb(pcap_pathname);
1012         if ( fdpcap ) {
1013                 fdpcap = read_pcap_head(fdpcap, &pfh, &read_count);
1014                 if (0 != fdpcap) {
1015                         _tprintf("press [s] to break, any other keys to show pcap file header data.....\n");
1016                         chget = getchar();
1017                         if (chget == 's') {
1018                                 _my_pcap_close(fdpcap);
1019                                 return;
1020                         }
1021                         print_pcap_head(&pfh);
1022                         while (!(chget == 's')) {
1023                                 _tprintf("press [s] to break, any other keys to continue showing pcap packet header data......\n");
1024                                 chget = getchar();
1025                                 if (chget == 's') {
1026                                         break;
1027                                 }
1028                                 fdpcap = read_pcap_packet_head(fdpcap, &pph, pfh.magic, &read_count);
1029                                 if (0 != fdpcap) {
1030                                         pckt_count++;
1031                                         _tprintf("pcap data packet header count %d\n", pckt_count);
1032                                         print_pcap_packet_head(&pph);
1033                                         _tprintf("press [s] to break, any other keys to continue showing pcap packet content data.......\n");
1034                                         chget = getchar();
1035                                         if (chget == 's') {
1036                                                 break;
1037                                         }
1038                                         ppd = (u8 *)_my_malloc((size_t)(pph.caplen));
1039                                         fdpcap = read_pcap_packet_data(fdpcap, ppd, pph.caplen, &read_count);
1040                                         if ( 0 != fdpcap) {
1041                                                 print_pcap_packet_data(ppd, pph.caplen);
1042 
1043                                                 curr_pdf = (_my_i92p_rwptr)ppd;
1044                                                 curr_pdf = read_svpdu_lpdu_head(curr_pdf, pph.caplen, &lpdu_head, &read_count);
1045                                                 if (0 == curr_pdf) {
1046                                                         _tprintf("press [s] to break, read error...\n");
1047                                                         chget = getchar();
1048                                                         if (chget == 's') {
1049                                                                 break;
1050                                                         }
1051                                                 }
1052                                                 else {
1053                                                         print_svpdu_lpdu_head(&lpdu_head);
1054                                                         _tprintf("press [s] to break, any other keys to continue...\n");
1055                                                         //        chget = getchar();
1056                                                         if (chget == 's') {
1057                                                                 break;
1058                                                         }
1059                                                 }
1060 
1061                                                 curr_pdf = read_svpdu_apdu_head(curr_pdf, pph.caplen, &apdu_head, &read_count);
1062                                                 if (0 == curr_pdf) {
1063                                                         _tprintf("press [s] to break, read error...\n");
1064                                                         chget = getchar();
1065                                                         if (chget == 's') {
1066                                                                 break;
1067                                                         }
1068                                                 }
1069                                                 else {
1070                                                         print_svpdu_apdu_head(&apdu_head);
1071                                                         _tprintf("press [s] to break, any other keys to continue...\n");
1072                                                         chget = getchar();
1073                                                         if (chget == 's') {
1074                                                                 break;
1075                                                         }
1076                                                 }
1077 
1078                                                 for (index = 0; index<apdu_head.asdu_num_value; index ++) {
1079                                                         _tprintf("read  asdu_dat92 %d\n", index);
1080                                                         init_svpdu_asdu_dat92(&asdu_dat92);
1081                                                         curr_pdf = read_svpdu_asdu_dat92(curr_pdf, pph.caplen, &asdu_dat92, smpquality_enable, &read_count);
1082                                                         if (0 == curr_pdf) {
1083                                                                 _tprintf("press [s] to break, read error...\n");
1084                                                                 chget = getchar();
1085                                                                 if (chget == 's') {
1086                                                                         break;
1087                                                                 }
1088                                                         }
1089                                                         else {
1090                                                                 print_svpdu_asdu_dat92(&asdu_dat92, smpquality_enable);
1091                                                                 _tprintf("press [s] to break, any other keys to continue...\n");
1092                                                                 chget = getchar();
1093                                                                 if (chget == 's') {
1094                                                                         break;
1095                                                                 }
1096                                                         }
1097                                                 }//*/
1098 
1099                                                 free(ppd);
1100                                                 ppd = 0;
1101                                                 continue;
1102                                         }
1103                                         free(ppd);
1104                                         ppd = 0;
1105                                 }
1106                                 break;
1107                         }
1108                 }
1109                 _my_pcap_close(fdpcap);
1110         }
1111 }
1112 
1113 
1114 /*
1115  * i92p_test_demo2 - 测试函数,创建9-2包,并且读出来
1116  * @pcap_pathname:  pcap文件路径
1117  * @packet_pathname:  pcaket文件路径
1118  *
1119  */
1120 void i92p_test_demo2(const char* pcap_pathname, u8 smpquality_enable)
1121 {
1122         int index = 0;
1123 
1124         pcap_head pfh;
1125         pcap_packet_head pph;
1126 
1127         svpdu_lpdu_head lpduh;
1128         svpdu_apdu_head apduh;
1129         svpdu_asdu_dat92 asdu92;
1130 
1131         init_svpdu_asdu_dat92(&asdu92, true);
1132 
1133 /*
1134         asdu92->asdu_tag =
1135         for (intdex = 0;)
1136 
1137         _my_pcap_ioptr fdpcap = 0;
1138 
1139         fdpcap = _my_pcap_openwb(pcap_pathname);
1140 
1141         _my_svpdu_ioptr curr_pdf = 0;
1142 
1143 
1144         int pckt_count = 0;
1145         int write_count = 0;
1146 
1147 
1148         u8* ppd = 0;
1149         pcap_head pfh;
1150         pcap_packet_head pph;
1151 
1152         _my_svpdu_ioptr curr_pdf = 0;
1153         int bgn_pos = 0;
1154         int end_pos = 0;
1155 
1156         int index = 0;
1157         int count = 0;
1158 
1159         char chget;
1160 
1161         _my_pcap_ioptr fdpcap = 0;
1162 
1163         svpdu_lpdu_head lpdu_head;
1164         svpdu_apdu_head apdu_head;
1165         svpdu_asdu_dat92 asdu_dat92;
1166 
1167         fdpcap = _my_pcap_openrb(pcap_pathname);
1168         if ( fdpcap ) {
1169                 fdpcap = read_pcap_head(fdpcap, &pfh, &read_count);
1170                 if (0 != fdpcap) {
1171                         _tprintf("press [s] to break, any other keys to show pcap file header data.....\n");
1172                         chget = getchar();
1173                         if (chget == 's') {
1174                                 _my_pcap_close(fdpcap);
1175                                 return;
1176                         }
1177 */
1178 }
1179 
1180 
1181 /*
1182  * main - 测试main函数
1183  *
1184  */
1185 int main(int argc, char* argv[]) {
1186         char pcap_pathname[255];
1187 
1188         char chget;
1189 
1190                 u8 smpquality_enable = 1;
1191 //        while (1) {
1192                 memset(pcap_pathname, 0, 255);
1193                 _tprintf("please input pacp file full path name:\n");
1194                 //gets(pcap_pathname);
1195 
1196                 //i92p_test_demo(pcap_pathname, smpquality_enable);
1197                 i92p_test_demo1("D:/KRTV2_KF900/9-2lubo/09160016", smpquality_enable);
1198                 //i92p_test_demo("D:/1.pcap", smpquality_enable);
1199 
1200                 printf("press [s] to break,any other keys to continue end.\n");
1201                 chget = getchar();
1202                 if (chget == 's') {
1203                 //        break;
1204                 }
1205 //        }
1206 
1207         return 0;
1208 }
1209 
1210 #endif /* I92P_CONSOLE_DEMO */
原文地址:https://www.cnblogs.com/lizhi0755/p/3095960.html