📄 nz_sf.c
字号:
{ ret =IEC_PackInspectEnd_TCP(IEC104DataBuf_M,SubDevice[iPort].SubStations[index].sub_address,1, pSub->sub_FUN,pucCMD[IEC103_OFFSET_CONTEXT]); CONN_Send104Data(NetGroup,iConnect_inspect,IEC104DataBuf_M,ret); } iConnect_inspect=0xff; } if(SubDevice[iPort].SubStations[index].sub_DZendflag ==1) { SYS_Delay(20); SubDevice[iPort].SubStations[index].sub_DZendflag = 0; ucINF =100; ret = IEC_PackEND_TCP(IEC104DataBuf_M,SubDevice[iPort].SubStations[index].sub_address, ucGlobalCPU,SubDevice[iPort].SubStations[index].sub_FUN ,ucINF); CONN_Send104Data(NetGroup,iConnect_dz,IEC104DataBuf_M,ret); iConnect_dz=0xff; } break; default : ucCS =0; break; } if (ucCS & _ACD) //if has first user data { iSend =LocalIEC103Cmd(REQUIREFIRSTDATA, ucADDR, pucCMD); } else //if no first user data { pSub->sub_CS =REQUIRESECONDDATA; if(ucCS==0x0E) //装置回答链路未准备好,复位装置通信单元 pSub->sub_CS=RESETCU; } break; } else { pSub->sub_FailNum++; ucCS = 0; } } if (i==3) { if (pSub->sub_state == SUB_STATE_ONLINE) { pSub->sub_state =SUB_STATE_FAIL; } break; } }while(ucCS & _ACD); //loop until have no first user data return 0;}/*=============================================================*//*FUNCTION :通用分类命令 *//*INPUT PARAMETER :ucAddr --装置地址 *//* pDest --指定的发送缓冲区 *//*RETURN :命令的总字节数 *//*=============================================================*/int LocalGENERICcmd(int iPort,unsigned char ucAddr,unsigned char ucGIN,unsigned char *pDest) { int i,sum,index; unsigned char *p1 =pDest,ucFCB; index =SUB_AddrToIndex(ucAddr); ucFCB =SUB_GetFCB(ucAddr); *p1 = *(p1+3) =START_CODE2; //起始符 *(p1+1) = *(p1+2) =13; //长度 *(p1+IEC103_OFFSET_ADDR) =ucAddr; *(p1+IEC103_OFFSET_CODE) =0x53; SUB_SetFCB(p1,ucFCB); //设置FCB,FCV *(p1+IEC103_OFFSET_TI) =21; //ASDU_21 *(p1+IEC103_OFFSET_VSQ) =0x81; *(p1+IEC103_OFFSET_COT) =42; *(p1+IEC103_OFFSET_COMADDR) =ucAddr; *(p1+IEC103_OFFSET_FUN) =254; *(p1+IEC103_OFFSET_INF) =241; *(p1+IEC103_OFFSET_RII) =0;//SubDevice[iPort].SubStations[index].sub_RII; *(p1+IEC103_OFFSET_NGD) =1; *(p1+IEC103_OFFSET_GIN) =ucGIN;//组号 *(p1+IEC103_OFFSET_GIN+1) =0x00; *(p1+IEC103_OFFSET_KOD) =0x01; //实际值 sum =0; for(i =0 ;i <*(p1+1) ;i++) { sum +=*(p1+i+4); } *(p1+i+4) = sum ; *(p1+i+5) = END_CODE; return 19;} /**********************************四方保护(103规约)********************************************/int SF103_To_XJ104(unsigned char *puc104,unsigned char *puc103){ CurrentTime CurTime; GW_Global *pGlobal=&gwGlobal; int iPort,i,index; unsigned char ucTI104,ucTI103,ucInf103,ucCOT103,ucData; unsigned char *p1=puc104,*p2=puc103,ucADDR; unsigned long ulInf104,uBase; unsigned int uiCOT104,uiINF103; unsigned int num,offset,ucLen,wValue; ucADDR=*(p2+IEC103_OFFSET_ADDR); index = SUB_AddrToIndex(ucADDR); iPort = SUB_AddrToPort(ucADDR); ucTI103 = *(p2+IEC103_OFFSET_TI); ucInf103 = *(p2+IEC103_OFFSET_INF); ucCOT103 = *(p2+IEC103_OFFSET_COT); uiCOT104 = IEC_COT_103To104(*(p2+IEC103_OFFSET_COT)); ulInf104 = 0; if((ucInf103==0x1d)&&(ucCOT103==9)) //南自不上送总召唤结束帧,需自设一个总召唤结束标志 SubDevice[iPort].SubStations[index].sub_InspectEnd=1; //装置响应总召唤上送数据为固定的一张表,INF=0x1d是最后一个数据 *p1 = START_CODE2; *(p1+2) = 0; *(p1+3) = 0; *(p1+4) = 0; *(p1+5) = 0; *(p1+IEC104_OFFSET_LEN) = 0; *(p1+IEC104_OFFSET_VSQ) = *(p2+IEC103_OFFSET_VSQ) ^ 0x80; //SQ Bit reserve *(p1+IEC104_OFFSET_COT) = uiCOT104 & 0xff; *(p1+IEC104_OFFSET_COT+1) = (uiCOT104 >> 8) & 0xff; *(p1+IEC104_OFFSET_ADDR) = SubDevice[iPort].SubStations[index].sub_address; switch(ucTI103) { case IEC103_TI_M_TM_TA_3://告警信号硬压板都用ASDU_1 硬压板遥信状态报文或告警信号 ulInf104 = (unsigned long)ucInf103; *(p1+IEC104_OFFSET_INF) =ulInf104&0xff; *(p1+IEC104_OFFSET_INF+1) =(ulInf104>>8)&0xff; *(p1+IEC104_OFFSET_INF+2) =(ulInf104>>16)&0xff; *(p1+IEC104_OFFSET_SECT) = 1; if(ucCOT103 ==1) //变位时上送的信息 { *(p1+IEC104_OFFSET_TI) =IEC104_TI_M_DP_TB_1; //ASDU_31,0x1F for(i=0 ; i< 5 ; i++) { *(p1+IEC104_OFFSET_CONTEXT+i)=*(p2+IEC103_OFFSET_CONTEXT+i); } CurTime = GetTime(); *(p1+IEC104_OFFSET_CONTEXT+5) = CurTime.day; *(p1+IEC104_OFFSET_CONTEXT+6) = CurTime.month; *(p1+IEC104_OFFSET_CONTEXT+7) = CurTime.year; *(p1+IEC104_OFFSET_LEN) = MIN_IEC104_FRAMELEN + 8;//7 for CurTime,1 for spi(dpi) } else if(ucCOT103==9) //总召唤时上送的信息 { *(p1+IEC104_OFFSET_TI) = 3; *(p1+IEC104_OFFSET_CONTEXT) = *(p2+IEC103_OFFSET_CONTEXT); *(p1+IEC104_OFFSET_LEN) = MIN_IEC104_FRAMELEN + 1; } else return 0; break; case 2: //保护动作 *(p1+IEC104_OFFSET_SECT) = 2 ; *(p1+IEC104_OFFSET_TI) = IEC104_TI_M_EP_TD_1; //ASDU_38 ulInf104 = (unsigned long)ucInf103; *(p1+IEC104_OFFSET_VSQ) =0x01; *(p1+IEC104_OFFSET_INF) =ulInf104&0xff; *(p1+IEC104_OFFSET_INF+1) =(ulInf104>>8)&0xff; *(p1+IEC104_OFFSET_INF+2) =(ulInf104>>16)&0xff; *(p1+IEC104_OFFSET_CONTEXT) =*(p2+IEC103_OFFSET_CONTEXT); //DPI *(p1+IEC104_OFFSET_CONTEXT+1) =0;//*(p2+IEC103_OFFSET_CONTEXT+1); *(p1+IEC104_OFFSET_CONTEXT+2) =0;//*(p2+IEC103_OFFSET_CONTEXT+2); for (i=0 ; i<4 ; i++) { *(p1+IEC104_OFFSET_CONTEXT+3+i) = *(p2+IEC103_OFFSET_CONTEXT+5+i); //skip fault number } *(p1+IEC104_OFFSET_CONTEXT+7) =CurTime.day; *(p1+IEC104_OFFSET_CONTEXT+8) =CurTime.month; *(p1+IEC104_OFFSET_CONTEXT+9) =CurTime.year; //7 for CurTime,1 for dpi,2 for relative CurTime *(p1+IEC104_OFFSET_LEN) =MIN_IEC104_FRAMELEN + 10; break; case 10: // 闫黎明添加 if((*(p2+IEC103_OFFSET_INF)==241)&&(*(p2+IEC103_OFFSET_GIN) ==0x01))//读取保护测量值 { *(p1+IEC104_OFFSET_TI) =IEC104_TI_M_ME_NA_1; ucLen =(*(p2+IEC103_OFFSET_VSQ)) & 0x7F; *(p1+IEC104_OFFSET_VSQ) = 0x80|(*(p2+IEC103_OFFSET_VSQ)); ulInf104 = 0x4001+ucInf103; *(p1+IEC104_OFFSET_INF) =ulInf104 & 0xff; *(p1+IEC104_OFFSET_INF+1) =(ulInf104 >> 8) & 0xff; *(p1+IEC104_OFFSET_INF+2) =(ulInf104 >> 16) & 0xff; for (i=0 ; i< ucLen ; i++) { wValue = GetYCValue(p2+20+i*10); *(p1+IEC104_OFFSET_CONTEXT+i*3) =wValue%256; *(p1+IEC104_OFFSET_CONTEXT+i*3+1) =wValue/256; *(p1+IEC104_OFFSET_CONTEXT+i*3+2) =0; } *(p1+IEC104_OFFSET_LEN) = MIN_IEC104_FRAMELEN+3*ucLen; } break; default : break; } return (*(p1+IEC104_OFFSET_LEN)+2);}/*FUNCTION :change data form IEC104 protocol to IEC103 protocol(for operator&remote station)*//*INPUT PARAMETER: pucIEC103 --dest data buffer address*//* pucIEC104 --source data buffer address*//*OUTPUT : --length of dest data buffer*/int XJ104_To_SF103(int iPort,unsigned char *puc103,unsigned char *puc104){ CurrentTime CurTime; GW_Global *pGlobal =&gwGlobal; int i,index; unsigned char ucTI104,ucTI103,ucCOT104; unsigned char *p1=puc103,*p2=puc104,sum,ucData; unsigned int uiInfRcs; unsigned long ulInf104; unsigned char ucFCB=0; unsigned char ucADDR,ucGroup; ucADDR = *(p2+IEC104_OFFSET_ADDR); index = SUB_AddrToIndex(ucADDR); ucFCB = SUB_GetFCB(ucADDR); ulInf104 = ((unsigned long)*(p2+IEC104_OFFSET_INF+1)&0xff) * 0x100 + ((unsigned long)*(p2+IEC104_OFFSET_INF)&0xff); ucCOT104= *(p2+IEC104_OFFSET_COT); ucTI104 = *(p2+IEC104_OFFSET_TI); *p1 =*(p1+3) =START_CODE2; *(p1+IEC103_OFFSET_CODE) =0x53; if(ucADDR!=BROADCAST_ADDR) { *(p1+IEC103_OFFSET_ADDR) = ucADDR; } else { *(p1+IEC103_OFFSET_ADDR) = 0xff; } *(p1+IEC103_OFFSET_VSQ) =*(p2+IEC104_OFFSET_VSQ) ^ 0x80; *(p1+IEC103_OFFSET_COT) =IEC_COT_104To103(*(p2+IEC104_OFFSET_COT)); *(p1+IEC103_OFFSET_COMADDR) =*(p2+IEC104_OFFSET_ADDR) ; *(p1+IEC103_OFFSET_FUN) =SUB_GetFUN(*(p2+IEC104_OFFSET_ADDR)); *(p1+IEC103_OFFSET_INF) =0x0; switch(ucTI104) { case IEC104_TI_C_CS_NA_1: //clock synchronization command,ASDU_103 CurTime = GetTime(); *(p1+IEC103_OFFSET_CODE) =0x44; //*(p1+4) *(p1+IEC103_OFFSET_ADDR) =0xFF; *(p1+IEC103_OFFSET_TI) =6; //IEC103_TI_M_SYN_TA_3; *(p1+IEC103_OFFSET_COT) =8; //时间同步 *(p1+IEC103_OFFSET_COMADDR) =0xFF; *(p1+IEC103_OFFSET_FUN) =0xFF; *(p1+IEC103_OFFSET_INF) =0x00; *(p1+IEC103_OFFSET_CONTEXT) =CurTime.mSecond & 0xff; *(p1+IEC103_OFFSET_CONTEXT+1) =(CurTime.mSecond >> 8) & 0xff; *(p1+IEC103_OFFSET_CONTEXT+2) =CurTime.minute; *(p1+IEC103_OFFSET_CONTEXT+3) =CurTime.hour; *(p1+IEC103_OFFSET_CONTEXT+4) =CurTime.day; *(p1+IEC103_OFFSET_CONTEXT+5) =CurTime.month; *(p1+IEC103_OFFSET_CONTEXT+6) =CurTime.year; *(p1+1) = *(p1+2) = MIN_IEC103_FRAMELEN+7; break; case IEC104_TI_C_IC_NA_1: //interrogation command,general inspect ,ASDU_100,总召唤启动 SubDevice[iPort].SubStations[index].sub_SCN104 =*(p2+IEC104_OFFSET_CONTEXT); *(p1+IEC103_OFFSET_TI) =IEC103_TI_C_IGI_NA_3; //7 *(p1+IEC103_OFFSET_COT) =IEC103_COT_M_totalQUERY; //9 *(p1+IEC103_OFFSET_FUN) =0xFF; *(p1+IEC103_OFFSET_INF) =0x00; *(p1+IEC103_OFFSET_CONTEXT) =SubDevice[iPort].SubStations[index].sub_SCN104 ; //扫描序号? *(p1+1) = *(p1+2) =MIN_IEC103_FRAMELEN+1; break; case IEC104_TI_C_DC_NA_1: //double-point command,ASDU_46,双点遥控命令 if (SUB_DeviceOn( *(p2+IEC104_OFFSET_ADDR) ) ||*(p2+IEC104_OFFSET_ADDR)==0xff) { if( ((pGlobal->Protocol_Version == XJ_IEC_1)&&(ulInf104==0xb14)) ||((pGlobal->Protocol_Version == XJ_IEC_2)&&(ulInf104==0x6014)) ) //信号复归 { *(p1+IEC103_OFFSET_TI) =20; //IEC103_TI_C_GRC_NA_3;一般命令 *(p1+IEC103_OFFSET_COT) =20; *(p1+IEC103_OFFSET_INF) =19; *(p1+IEC103_OFFSET_CONTEXT) =*(p2+IEC104_OFFSET_CONTEXT); *(p1+IEC103_OFFSET_CONTEXT+1) =0; //SII *(p1+1)=*(p1+2) =MIN_IEC103_FRAMELEN+2; } } break; default : return 0; } if ( (*(p1+1))>=MIN_IEC103_FRAMELEN ) { SUB_SetFCB(p1,ucFCB); sum =0; for (i =0 ;i <*(p1+1) ;i++) { sum +=*(p1+i+4); } *(p1+i+4) = sum & 0xff; *(p1+i+5) = END_CODE; return (*(p1+1)+6); } else { return 0; }}/*=====================================================================*//*FUNCTION :将IEC103协议转为TCP103/*PARAMETER:pucTCP/* puc103/*RETURN :TCP103总的字节个数/*=====================================================================*/int SF103_To_XJTCP(unsigned char *pucTCP, unsigned char *puc103){ CurrentTime CurTime; int index,iPort; unsigned int i,pos; unsigned char ucADDR,totalnum =0,offset; unsigned char ucTI,ucCOT103,ucInf103; unsigned char *p1=pucTCP,*p2=puc103; static unsigned char error=0; CurTime = GetTime(); ucCOT103=*(p2+IEC103_OFFSET_COT); ucInf103=*(p2+IEC103_OFFSET_INF); ucADDR = *(p2+IEC103_OFFSET_ADDR); iPort = SUB_AddrToPort(ucADDR); index = SUB_AddrToIndex(ucADDR); *p1 = START_CODE2; //Start Code *(p1+1) = *(p2+1)+4 ; //Frame length *(p1+TCP_OFFSET_CODE) = 0; *(p1+TCP_OFFSET_CODE+1) = 0; *(p1+TCP_OFFSET_CODE+2) = 0; *(p1+TCP_OFFSET_CODE+3) = 0; *(p1+TCP_OFFSET_VSQ) = *(p2+IEC103_OFFSET_VSQ); *(p1+TCP_OFFSET_COMADDR) = 1; *(p1+TCP_OFFSET_ADDR) = SubDevice[iPort].SubStations[index].sub_address; *(p1+TCP_OFFSET_FUN) = SubDevice[iPort].SubStations[index].sub_FUN; *(p1+TCP_OFFSET_INF) = ucInf103; ucTI = *(p2+IEC103_OFFSET_TI); if((ucInf103==0x1d)&&(ucCOT103==9)) SubDevice[iPort].SubStations[index].sub_InspectEnd=1; switch(ucTI) { case 5: case 23: return 0; case 10: //通用分类命令响应 if((*(p2+IEC103_OFFSET_INF)==241)&&(*(p2+IEC103_OFFSET_GIN) ==0x04)) { *(p1+TCP_OFFSET_TI) =61; *(p1+TCP_OFFSET_CONTEXT) =ucDZcpu+0x01; //定值区号:当前区 SubDevice[iPort].SubStations[index].sub_RII =*(p2+IEC103_OFFSET_RII); if(*(p2+IEC103_OFFSET_COT)==43) //无定值回答 { *(p1+TCP_OFFSET_VSQ) =0x81; *(p1+TCP_OFFSET_COT) =21; *(p1+TCP_OFFSET_INF) =100; *(p1+TCP_OFFSET_CONTEXT+1) =0; *(p1+TCP_OFFSET_LEN) =MIN_TCP_FRAMELEN+2; } else //有定值回答 { offset=14; totalnum =*(p2+IEC103_OFFSET_NGD)& 0x3f; *(p1+TCP_OFFSET_VSQ) =totalnum+1; *(p1+TCP_OFFSET_COT) =20; *(p1+TCP_OFFSET_INF) =100; *(p1+TCP_OFFSET_COMADDR) =ucDZcpu>>4; *(p1+TCP_OFFSET_CONTEXT+1) =*(p2+IEC103_OFFSET_GIN+1)-1; //定值1在当前区的位置顺序号 0?1 DZValue103_TCP(totalnum,offset,p1,p2) ; *(p1+TCP_OFFSET_LEN) =MIN_TCP_FRAMELEN+2+totalnum*3; if( (*(p2+IEC103_OFFSET_NGD)& 0x80) == 0 ) { SubDevice[iPort].SubStations[index].sub_DZendflag =1; } } return (*(p1+1)+2); } else return 0; case 1: for(i=pos=IEC103_OFFSET_TI; i<(*(p2+1)-2+IEC103_OFFSET_TI); i++)//IEC103_OFFSET_TI=6; { if (i==IEC103_OFFSET_COT) { *(p1+pos++) =*(p2+i); *(p1+pos++) =0; } else if (i==IEC103_OFFSET_COMADDR) { *(p1+pos++) =*(p2+i); *(p1+pos++) =*(p2+IEC103_OFFSET_ADDR); } else *(p1+pos++) =*(p2+i); } *(p1+TCP_OFFSET_COMADDR) =1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -