• 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 */
  • 相关阅读:
    linux系统--磁盘管理命令(二)
    linux系统--磁盘管理命令(一)
    linux系统--用户和用户组
    linux4.10.8 内核移植(四)---字符设备驱动_led驱动程序
    linux4.10.8 内核移植(三)---裁剪内核
    linux4.10.8 内核移植(二)---初步裁剪、分区修改和文件系统
    Linux 4.10.8 根文件系统制作(三)---制作yaffs文件系统
    Kotlin的面向对象入门
    Python 中的GIL
    python 虚拟环境的 安装与 使用 和修改为豆瓣源
  • 原文地址:https://www.cnblogs.com/lizhi0755/p/3095960.html
Copyright © 2020-2023  润新知