www.pudn.com > rtu.rar > IEC101.C
//
// File name =IEC101Link.C //串行通信IEC101Link维护软件规约程序
//设计 何风涛
#include"class.h"
#include "classext.h"
void IEC101LinkTask(struct TIEC101LinkStruct FARDATA *Arg);
void IEC101LinkRx(struct TIEC101LinkStruct FARDATA *Arg);
void IEC101LinkTx(struct TIEC101LinkStruct FARDATA *Arg);
void IEC101LinkCommand(struct TIEC101LinkStruct FARDATA *Arg);
void IEC101LinkComTrans(struct TIEC101LinkStruct FARDATA *Arg);
void Ack(struct TIEC101LinkStruct FARDATA *Arg);
void Nak(struct TIEC101LinkStruct FARDATA *Arg,unsigned char NakNo);
void IEC101LinkSendAFrame(struct TIEC101LinkStruct FARDATA *Arg);
void IEC101LinkRecFile(struct TIEC101LinkStruct FARDATA *Arg);
void IEC101LinkAck(struct TIEC101LinkStruct FARDATA *Arg);
void IEC101LinkNak(struct TIEC101LinkStruct FARDATA *Arg);
char RxdCrc(struct TIEC101LinkStruct FARDATA *Arg);
unsigned int Crc16(unsigned char FARDATA *ptr,int count);
unsigned char FileError(struct TIEC101LinkStruct FARDATA *Arg);
unsigned char RTUStatus(struct TIEC101LinkStruct FARDATA *Arg);
void IEC101LinkTimer(struct TIEC101LinkStruct FARDATA *Arg);
unsigned int readfile(void FARDATA *dbuf,size_t maxl,FILE *fp);
void FileName(struct TIEC101LinkStruct FARDATA *Arg);
void IEC101LinkSendFrame(struct TIEC101LinkStruct FARDATA *Arg);
void IEC101LinkFileSend(struct TIEC101LinkStruct FARDATA *Arg);
void LoadFile(struct TIEC101LinkStruct FARDATA *Arg);
struct TIEC101LinkStruct FARDATA *InitIEC101Link(int ComTaskNo)
{
struct TIEC101LinkStruct FARDATA *Arg;
if((Arg=(struct TIEC101LinkStruct FARDATA *)malloc(sizeof(struct TIEC101LinkStruct)))==NULL)
{
return(NULL);
}
memset(Arg,0,sizeof(struct TIEC101LinkStruct));
Arg->ComTaskNo=ComTaskNo;
Arg->RxdStatus=START;
if((Arg->TxdBuf=(unsigned char FARDATA *)malloc(1024*sizeof(char)))==NULL)
{
return(NULL);
}
Arg->TxdStatus=WAIT;
Arg->Ykcomm=yknull;
Arg->StatusCode=1;
Arg->Letter_from_box=boxnull;
Arg->ReadFlag=0;
Arg->LinkStatus=LinkOFF;
Arg->ComMode=SubStation;
if((Arg->RxdBuf=(unsigned int FARDATA *)malloc(1024*sizeof(int)))==NULL)
{
return(NULL);
}
if((Arg->RecBuf=(unsigned char FARDATA *)malloc(2048*sizeof(char)))==NULL)
{
return(NULL);
}
if((Arg->TrnLetter=(unsigned char FARDATA *)malloc(260*sizeof(char)))==NULL)
{
return(NULL);
}
if((Arg->RecLetter=(unsigned char FARDATA *)malloc(260*sizeof(char)))==NULL)
{
return(NULL);
}
return(Arg);
}
void IEC101Link(struct TIEC101LinkStruct FARDATA *Arg)
{
if(TaskStatus(Arg->ComTaskNo) & 0x02) IEC101LinkRx(Arg); // Rx Task
if(TaskStatus(Arg->ComTaskNo) & 0x01) IEC101LinkTx(Arg); // Tx Task
if(TaskStatus(Arg->ComTaskNo) & 0x80) IEC101LinkTimer(Arg);// 定时监视
}
unsigned char SFrameCS(struct TIEC101LinkStruct FARDATA *Arg)
{/* 固定帧格式校验 */
unsigned char ch,cs;
cs=0xff;
switch(Arg->FrameStatus)
{
case 0x10:Arg->RxdBufLength=Tgets(Arg->ComTaskNo,4,Arg->RxdBuf);
if(Arg->RxdBufLength==4)
{
Arg->LinkControl=(*(Arg->RxdBuf+0));
Arg->Linkadr= (*(Arg->RxdBuf+1));
Arg->LinkCS= (*(Arg->RxdBuf+2));
Arg->LinkEnd= (*(Arg->RxdBuf+3));
if(Arg->LinkEnd==0x16)
{
ch=Arg->LinkControl+Arg->Linkadr;
if(ch==Arg->LinkCS) cs=0;
}
}
break;
case 0x68:Arg->RxdBufLength=Tgets(Arg->ComTaskNo,5,Arg->RxdBuf);
if(Arg->RxdBufLength==5)
{
Arg->RxdFrameLength=(*(Arg->RxdBuf+0));
if(Arg->RxdFrameLength==(*(Arg->RxdBuf+1)))
{
if(Arg->RxdFrameLength>=2)
{
if((*(Arg->RxdBuf+2))==0x68)
{
Arg->LinkControl=(*(Arg->RxdBuf+3));
Arg->Linkadr= (*(Arg->RxdBuf+4));
cs=0;
}
}
}
}
break;
}
return cs;
}
void HFrameAct(struct TIEC101LinkStruct FARDATA *Arg)
{/* 帧处理 */
union WTEMP_ST T;
T.Word=(UINT)Tgetc(Arg->ComTaskNo);
switch(Arg->FrameStatus)
{
case 0x10:if(SFrameCS(Arg))
{/* 接收错误 */
return;
}
Arg->TrnLetter[0]=8; //长度
Arg->TrnLetter[1]=Arg->UpTaskNo; //目的任务号
Arg->TrnLetter[2]=Arg->TaskNo; //源任务号
Arg->TrnLetter[3]=0; //帧状态
Arg->TrnLetter[4]=0x00; //固定帧
Arg->TrnLetter[5]=0x00; //帧长度
Arg->TrnLetter[6]=Arg->LinkControl;//控制帧
Arg->TrnLetter[7]=Arg->Linkadr; //链路域地址
if(TWrite(Arg->TrnLetter))
{
}else
{
Nak(Arg,11); //链路忙
}
break;
case 0x68:if(SFrameCS(Arg))
{/* 接收错误 */
return;
}
if(Arg->RxdFrameLength==2)
{
Arg->TrnLetter[0]=8; //长度
Arg->TrnLetter[1]=Arg->UpTaskNo; //目的任务号
Arg->TrnLetter[2]=Arg->TaskNo; //源任务号
Arg->TrnLetter[3]=0; //帧状态
Arg->TrnLetter[4]=0x80; //可变帧
Arg->TrnLetter[5]=0x00; //帧长度
Arg->TrnLetter[6]=(*(Arg->RxdBuf+5)); //控制帧
Arg->TrnLetter[7]=(*(Arg->RxdBuf+6)); //链路域地址
if(TWrite(Arg->TrnLetter))
{
}else
{
Nak(Arg,11); //链路忙
}
return;
}
if((Arg->RxdFrameLength+5-Arg->RxdBufLength)<=128) ChangeProWarn(Arg->TaskNo,0,Arg->RxdFrameLength+5-Arg->RxdBufLength);
else ChangeProWarn(Arg->TaskNo,0,128);
Arg->RxdStatus=FRAME;
break;
default: break;
}
}
void IEC101LinkRx(struct TIEC101LinkStruct FARDATA *Arg)
{
unsigned char ch;
struct TComStruct FARDATA *Com;
union WTEMP_ST T;
Com=(struct TComStruct *)Task[Arg->ComTaskNo].DevPtr;//设备驱动表指针
T.Word=(UINT)Tgetc(Arg->ComTaskNo);
if(T.B.High!=0)
{/* 接收错误 */
return;
}
/*-------------- Receive start ------------------------------------*/
if(Arg->RxdStatus==START)
{
switch(T.B.Low)
{
case 0x10: ChangeProWarn(Arg->ComTaskNo,RXD_BUF_PRO,4);
Arg->RxdStatus=HEAD;
Arg->FrameStatus=0x10;
break;
case 0x68: ChangeProWarn(Arg->ComTaskNo,RXD_BUF_PRO,5);
Arg->RxdStatus=HEAD;
Arg->FrameStatus=0x68;
break;
default:Tgets(Arg->ComTaskNo,255,Arg->RxdBuf);
Arg->RxdBufLength=0;
return;
break;
}
}
/*------------------Receive head-----------------------------------*/
if((Arg->RxdStatus==HEAD)&&(TaskStatus(Arg->ComTaskNo) & 0x02))
{
HFrameAct(Arg);
}
/*---------------------Receive frame-----------------------------------*/
if((Arg->RxdStatus==FRAME) && (TaskStatus(Arg->ComTaskNo) & 0x02))
{
if((Arg->RxdFrameLength+5-Arg->RxdBufLength)<=128)
{
Arg->RxdBufLength +=Tgets(Arg->ComTaskNo,Arg->RxdFrameLength+5,(Arg->RxdBuf+Arg->RxdBufLength));
}else
{
Arg->RxdBufLength +=Tgets(Arg->ComTaskNo,128,(Arg->RxdBuf+Arg->RxdBufLength));
}
if(Arg->RxdBufLength >=(Arg->RxdFrameLength+5))
{
Arg->TrnLetter[0]=Arg->RxdFrameLength+5; //长度
Arg->TrnLetter[1]=Arg->UpTaskNo; //目的任务号
Arg->TrnLetter[2]=Arg->TaskNo; //源任务号
Arg->TrnLetter[3]=0; //帧状态
Arg->TrnLetter[4]=0x80; //可变帧
Arg->TrnLetter[5]=Arg->RxdFrameLength; //帧长度
for(i=0;iRxdFrameLength;i++)
{
Arg->TrnLetter[6+i]=(*(Arg->RxdBuf+5+i));
}
if(TWrite(Arg->TrnLetter))
{
}else
{
Nak(Arg,11); //链路忙
}
return;
};
if(Arg->RxdFrameLength+5-Arg->RxdBufLength<=128) ChangeProWarn(Arg->ComTaskNo,0,Arg->RxdFrameLength-Arg->RxdBufLength+5);
else ChangeProWarn(Arg->ComTaskNo,0,128);
return;
};
}
void IEC101LinkCommand(struct TIEC101LinkStruct FARDATA *Arg)
{
if(Arg->RxdBufLength>1024)
{
Tgets(Arg->ComTaskNo,255,Arg->RxdBuf);
Arg->RxdBufLength=0;
Arg->RxdStatus=START;
ChangeProWarn(Arg->ComTaskNo,0,1);
if(FileError(Arg)) Nak(Arg,1); // Receive Data error
return;
};
if(!RxdCrc(Arg)) // if CRC check error,clear RXD buffer;
{
Tgets(Arg->ComTaskNo,255,Arg->RxdBuf);
Arg->RxdBufLength=0;
Arg->RxdStatus=START;
ChangeProWarn(Arg->ComTaskNo,0,1);
if(FileError(Arg)) Nak(Arg,0x1); // Receive Data error
}else IEC101LinkComTrans(Arg);
ChangeProWarn(Arg->ComTaskNo,0,1);
Arg->RxdStatus=START;
}
char RxdCrc(struct TIEC101LinkStruct FARDATA *Arg)
{
unsigned int i,Length;
Length=(unsigned char)*(Arg->RxdBuf)+(unsigned char)*(Arg->RxdBuf+1)*256+7;
for(i=0;iRecBuf+i)=*(Arg->RxdBuf+i);
};
Length-=2;
i=Crc16((unsigned char FARDATA *)Arg->RecBuf,Length);
if(i==(*(Arg->RecBuf+Length+1)*256+*(Arg->RecBuf+Length))) return(0xff);
else return(0);
}
unsigned int Crc16(unsigned char FARDATA *ptr,int count)
{
unsigned int crc, i;
crc = 0;
while (--count >= 0)
{
crc = (crc ^ (((int)*ptr++) << 8));
for (i = 0; i < 8; ++i) if (crc & 0x8000) crc = ((crc << 1) ^ 0x1021);
else crc = crc << 1;
}
return (crc & 0xFFFF);
}
void IEC101LinkTx(struct TIEC101LinkStruct FARDATA *Arg)
{
unsigned char Num,OldNum;
if(Arg->TxdStatus==WAIT)
{
StopTxd(Arg->ComTaskNo);
return;
};
if((Arg->TxdBufLength - Arg->TxdPtr) <= 255) Num=Arg->TxdBufLength - Arg->TxdPtr;
else Num=255;
OldNum=Num;
Tputs(Arg->ComTaskNo,&Num,(char FARDATA *)(Arg->TxdBuf+Arg->TxdPtr));
Arg->TxdPtr +=OldNum-Num;
if(Arg->TxdBufLength<=Arg->TxdPtr) Arg->TxdStatus=WAIT;
}
void Ack(struct TIEC101LinkStruct FARDATA *Arg)
{
*(Arg->TxdBuf)=0;
*(Arg->TxdBuf+1)=0;
*(Arg->TxdBuf+2)=0x06;
*(Arg->TxdBuf+3)=0;
*(Arg->TxdBuf+4)=RTUStatus(Arg);
IEC101LinkSendAFrame(Arg);
}
void Nak(struct TIEC101LinkStruct FARDATA *Arg,unsigned char NakNo)
{
*(Arg->TxdBuf+0)=2;
*(Arg->TxdBuf+1)=0;
*(Arg->TxdBuf+2)=21;
*(Arg->TxdBuf+3)=NakNo;
*(Arg->TxdBuf+4)=RTUStatus(Arg);
*(Arg->TxdBuf+5)=*(Arg->RecBuf+2);
*(Arg->TxdBuf+6)=*(Arg->RecBuf+3);
IEC101LinkSendAFrame(Arg);
}
void IEC101LinkSendAFrame(struct TIEC101LinkStruct FARDATA *Arg)
{
int Length;
unsigned int Sum;
unsigned char Count;
unsigned char FARDATA *Frame;
unsigned int Crc;
unsigned int i;
Frame=Arg->TxdBuf;
Length=(*Frame+*(Frame+1)*256+5);
Sum=Length;
if(!(*(Arg->TxdBuf+3)&0x80))
{
Crc = 0;
while(--Length >= 0)
{
Crc = (Crc ^ (((int)*(Frame++)) << 8));
for (i = 0; i < 8; ++i)
if (Crc & 0x8000) Crc = ((Crc << 1) ^ 0x1021);
else Crc = Crc << 1;
};
Crc &= 0xFFFF;
*(Arg->TxdBuf+Sum)=Crc;
*(Arg->TxdBuf+Sum+1)=Crc>>8;
};
Sum += 2;
Tputc(Arg->ComTaskNo,1); //01H
ChangeProWarn(Arg->ComTaskNo,1,Sum);
SetTimer(Arg->ComTaskNo,0);
if(Sum >255) Count=255;
else Count=Sum;
Arg->TxdPtr=Count;
Tputs(Arg->ComTaskNo,&Count,(char FARDATA *)Arg->TxdBuf);
Arg->TxdBufLength=Sum;
Arg->TxdPtr -=Count;
if(Arg->TxdBufLength>Arg->TxdPtr) Arg->TxdStatus=SEND;
}
void IEC101LinkComTrans(struct TIEC101LinkStruct FARDATA *Arg)
{
unsigned int i;
// if(*(Arg->RecBuf+4)&0x02)//设备状态.D1=1 上装参数通讯失败
// for(i=0;iYCDNUM;i++) Arg->MYC[Arg->YCDNO[j]]=Arg->MYCtemp[j];
if(*(Arg->RecBuf+4)&0x80) //设备状态.D7=1
{
*(Arg->TxdBuf+3)|=0x80;//R是通讯出错传送标志,“1”表示该帧为重传的帧
IEC101LinkSendAFrame(Arg);
return;
};
switch(*(Arg->RecBuf+2)) //功能码
{
case 1:IEC101LinkRecFile(Arg); //文件传送
break;
case 2://遥测查询
break;
case 3://遥信查询
break;
case 4://电度查询
break;
case 5://事项顺序记录查询
break;
case 6://ACK对无需应答帧的确认,如分组传送中。
break;
case 7://trnsmit system status to notebook 系统状态
break;
case 8://yk operate 遥控操作
break;
case 10://高速采样
break;
case 11://reset 系统复位
Arg->TxdCode=0;
SystemReset();
break;
case 15://transparent data 透明数据传送
break;
case 16://时间
break;
case 17://变量查询
break;
case 18://故障录波
break;
case 21://NAK对接收错误帧的回执
break;
case 22://make system config file
break;
case 30://complex data packet 召唤全数据/召唤遥信遥测报文
break;
case 31://changed yc and yx 召唤变化数据数据报文
break;
default:if(FileError(Arg)) Nak(Arg,0);
break;
};
}
void IEC101LinkRecFile(struct TIEC101LinkStruct FARDATA *Arg) //文件传送
{
unsigned int i;
unsigned char command[64];
union WTEMP_ST T;
switch(*(Arg->RecBuf+3))
{
case 0://写方式打开文件(下装文件)
/* command[0]='\0';
strcpy((char FARDATA *)Arg->RecName,(char FARDATA *)(Arg->RecBuf+5));
strcat((char FARDATA *)command,(char FARDATA *)Arg->RecName);//串连接
fclose(Arg->fp);
if ((Arg->fp=fopen(command, "wb"))== NULL)
{
Nak(Arg,3);// Send File Nak for file open error
Arg->RxdCode=0;//NOUSE
}else
{//Send File Ack for file open OK with write mode;
Ack(Arg);
Arg->RxdPacketNo=0;
Arg->FileLength=0;
for(i=36;i>=33;i--)
{
Arg->FileLength <<=8;
Arg->FileLength +=*(Arg->RecBuf+i);
};
}; */
break;
case 1:// 读方式打开文件
/* T.B.Low=(*(Arg->RecBuf+5));
T.B.High=(*(Arg->RecBuf+6));
Arg->RxdPacketNo=T.Word;
if(Arg->RxdPacketNo==0)
{
Arg->TxdCode=0;
Arg->TxdPacketNo=0;
};
LoadFile(Arg); */
break;
case 2://Receive Text(struct TIEC101LinkStruct FARDATA *Arg); 正文传送
/* i=(*(Arg->RecBuf+5))+(*(Arg->RecBuf+6))*256;
if(i==(Arg->RxdPacketNo-1))
{
Ack(Arg);
break;
}
if(i!=Arg->RxdPacketNo)
{
Nak(Arg,2);
break;
};
Arg->RxdPacketLength=*(Arg->RecBuf)+*(Arg->RecBuf+1)*256-2;
fwrite(Arg->RecBuf+7,sizeof(char),Arg->RxdPacketLength,Arg->fp);
Arg->FileLength -=Arg->RxdPacketLength;
Arg->RxdPacketNo++;
Ack(Arg); */
break;
case 4:// SendEot(Struct TIEC101LinkStruct FARDATA *Arg); 正文传送结束
/* i=(*(Arg->RecBuf+5))+(*(Arg->RecBuf+6))*256;
if(i!= Arg->RxdPacketNo)
{
Nak(Arg,2);
break;
};
Arg->RxdPacketLength=*(Arg->RecBuf)+*(Arg->RecBuf+1)*256-2;
fwrite(Arg->RecBuf+7,sizeof(char),Arg->RxdPacketLength,Arg->fp);
Arg->FileLength -=Arg->RxdPacketLength;
fclose(Arg->fp);
Arg->RxdCode=0; //nouse;
if(Arg->FileLength==0)
{
Arg->STANo=0;
if((Arg->WriFlag==0xff)&&(strncmpi((char FARDATA *)Arg->RecName,"outfile.x1a",11)==0))
{
setdisk('e'-'a');
Arg->WriFlag=0;
Ack(Arg);
delay(3000);
}else
{
Arg->WriFlag=0;
Ack(Arg);
};
}else Nak(Arg,3); */
break;
case 5://传目录
/* FileName(Arg); */
break;
case 8:/*if(unlink((char FARDATA *)(Arg->RecBuf+5))==0) Ack(Arg);//文件删除
else Nak(Arg,5);
*/
break;
case 24:/*fclose(Arg->fp);
Ack(Arg);*/
break;
default:Nak(Arg,0);
};
}
unsigned char FileError(struct TIEC101LinkStruct FARDATA *Arg)
{
if(Arg->TxdCode !=0)
{
Arg->TxdRepeat--;
if((Arg->TxdRepeat)) //if((Arg->TxdRepeat-1)!=0)
{
*(Arg->TxdBuf+3)|=0x80;
IEC101LinkSendAFrame(Arg);
}else
{
if(*(Arg->TxdBuf+3)==0x82)
{
*(Arg->TxdBuf)=0;
*(Arg->TxdBuf+1)=0;
*(Arg->TxdBuf+2)=2;
*(Arg->TxdBuf+3)=24;
*(Arg->TxdBuf+4)=RTUStatus(Arg);
IEC101LinkSendAFrame(Arg);
}
}
return(0);
}
return(0xff);
}
void IEC101LinkNak(struct TIEC101LinkStruct FARDATA *Arg)
{
if(Arg->TxdCode !=0)
{
Arg->TxdRepeat--;
if((Arg->TxdRepeat))
{
*(Arg->TxdBuf+3)|=0x80;
IEC101LinkSendAFrame(Arg);
}else
{
if(*(Arg->TxdBuf+3)==0x82)
{
*(Arg->TxdBuf)=0;
*(Arg->TxdBuf+1)=0;
*(Arg->TxdBuf+2)=2;
*(Arg->TxdBuf+3)=24;
*(Arg->TxdBuf+4)=RTUStatus(Arg);
IEC101LinkSendAFrame(Arg);
}
};
}else
{
*(Arg->TxdBuf+3)|=0x80;
IEC101LinkSendAFrame(Arg);
}
}
void IEC101LinkAck(struct TIEC101LinkStruct FARDATA *Arg)
{
switch(Arg->TxdCode)
{
case 0:
break;
case 1:if(Arg->FileLength==0)
{
Arg->TxdCode=0;
return;
}
if(Arg->FileLength > IEC101LinkPACKETSIZE) //not the end packet
{
Arg->FileLength -=IEC101LinkPACKETSIZE;
Arg->TxdRepeat=IEC101LinkREPEAT;
*(Arg->TxdBuf ) =(IEC101LinkPACKETSIZE+1) & 0xFF;
*(Arg->TxdBuf+1)=(IEC101LinkPACKETSIZE+1) >> 8;
*(Arg->TxdBuf+2)=01;
*(Arg->TxdBuf+3)=02;//Text send
*(Arg->TxdBuf+4)=RTUStatus(Arg);
*(Arg->TxdBuf+5)=Arg->TxdPacketNo;
if(fread(Arg->TxdBuf+6,sizeof(char),IEC101LinkPACKETSIZE,Arg->fp)!=IEC101LinkPACKETSIZE)
{
Nak(Arg,5);
return;
}
IEC101LinkSendAFrame(Arg);
Arg->TxdPacketNo++;
}else // Send end packet of a file Send
{
Arg->TxdRepeat=IEC101LinkREPEAT;
*(Arg->TxdBuf)=(unsigned char)(Arg->FileLength+1) & 0xFF;
*(Arg->TxdBuf+1)=(unsigned char)(Arg->FileLength+1) >> 8;
*(Arg->TxdBuf+2)=01;
*(Arg->TxdBuf+3)=04;// end of Text send
*(Arg->TxdBuf+4)=RTUStatus(Arg);
*(Arg->TxdBuf+5)=Arg->TxdPacketNo;
if(fread(Arg->TxdBuf+6,sizeof(char),(size_t)Arg->FileLength,Arg->fp)!=(size_t)Arg->FileLength)
{
Nak(Arg,5);
return;
}
fclose(Arg->fp);
IEC101LinkSendAFrame(Arg);
Arg->FileLength =0;
};
break;
};
}
unsigned char RTUStatus(struct TIEC101LinkStruct FARDATA *Arg)
{
unsigned char i;
i=Arg->StatusCode;
return(i);
}
void IEC101LinkTimer(struct TIEC101LinkStruct FARDATA *Arg)
{
ResetTimer(Arg->ComTaskNo);
/*
Tgets(Arg->ComTaskNo,255,Arg->RxdBuf+7);
Arg->RxdBufLength=0;
Arg->RxdStatus=START;
ResetCom(Arg->ComTaskNo);
ChangeProWarn(Arg->ComTaskNo,0,1);
ChangeProWarn(Arg->ComTaskNo,1,1);
Nak(Arg,6); // Receive Data error
SetTimer(Arg->ComTaskNo,0); */
}
unsigned int readfile(void FARDATA *dbuf,size_t maxl,FILE *fp)
{
size_t i=0;
/* unsigned char FARDATA *dp;
rewind(fp);
dp=(unsigned char FARDATA *)dbuf;
while(!feof(fp) && (iRecBuf+5));
T.B.High=(*(Arg->RecBuf+6));
Arg->RxdPacketNo=T.Word;
if(T.Word==0) Arg->TxdPacketNo=0;
if(Arg->RxdPacketNo>5)Arg->RxdPacketNo=0;
i=(*(Arg->RecBuf+11));
if((i==0x43)||(i==0x63))
{
done=findfirst("c:\\*.*",&FileDAT,0);//0:成功,-1:失败
}else
{
done=findfirst("d:\\*.*",&FileDAT,0);//0:成功,-1:失败
}
for(i=0;i<80;i++)
{
if(done==0)
{
strcpy(str[i],FileDAT.ff_name);
FileNum++;
done=findnext(&FileDAT);
}else i=200;
};
for(i=0; iRxdCode=0;//NOUSE
Arg->RxdPacketNo=0;
}else
{
T.Word=FileNum*13;
LEN=T.Word;
dt=Arg->RxdPacketNo*245;
if(LEN>dt) j=LEN-dt;
else j=0;
if(j>245)
{
*(Arg->TxdBuf)=0xF5;
*(Arg->TxdBuf+1)=0;
*(Arg->TxdBuf+2)=0x01;
*(Arg->TxdBuf+3)=0x02;
*(Arg->TxdBuf+4)=RTUStatus(Arg);
*(Arg->TxdBuf+5)=Arg->RxdPacketNo;
*(Arg->TxdBuf+6)=0;
for(i=0; i<245; i++)
{
for(ii=0; ii<13; ii++) *(Arg->TxdBuf+7+13*i+ii)=*(FilePtr+dt+ii+13*i);
};
IEC101LinkSendFrame(Arg);
Arg->TxdPacketNo++;
}else
{
if(j!=0)
{
T.Word=j;
*(Arg->TxdBuf)=T.B.Low;
*(Arg->TxdBuf+1)=T.B.High;
*(Arg->TxdBuf+2)=0x01;
*(Arg->TxdBuf+3)=0x04;
*(Arg->TxdBuf+4)=RTUStatus(Arg);
*(Arg->TxdBuf+5)=Arg->RxdPacketNo;
*(Arg->TxdBuf+6)=0;
for(i=0; iTxdBuf+7+13*i+ii)=*(FilePtr+dt+ii+13*i);
};
IEC101LinkSendFrame(Arg);
Arg->TxdPacketNo++;
}else
{
*(Arg->TxdBuf)=0;
*(Arg->TxdBuf+1)=0;
*(Arg->TxdBuf+2)=0x01;
*(Arg->TxdBuf+3)=0x04;
*(Arg->TxdBuf+4)=RTUStatus(Arg);
*(Arg->TxdBuf+5)=Arg->RxdPacketNo;
*(Arg->TxdBuf+6)=0;
IEC101LinkSendFrame(Arg);
Arg->TxdPacketNo++;
}
}
};
*/
}
void LoadFile(struct TIEC101LinkStruct FARDATA *Arg)
{
/* switch(Arg->TxdCode)
{
case 0:fclose(Arg->fp);
if((Arg->fp=fopen((char FARDATA *)(Arg->RecBuf+7), "rb"))== NULL)
{
// Send File Nak for file open error
Nak(Arg,3);
Arg->RxdCode=0;//NOUSE
}else
{
Arg->TxdPacketNo=0;
if(fseek(Arg->fp,0,SEEK_END))
{
Nak(Arg,5);
return;
}
Arg->FileLength=ftell(Arg->fp);
if(fseek(Arg->fp,0,SEEK_SET))
{
Nak(Arg,5);
return;
}
Arg->TxdCode=1;
IEC101LinkFileSend(Arg);
};
break;
case 1:IEC101LinkFileSend(Arg);
break;
default :Nak(Arg,4);
Arg->RxdCode=0;//NOUSE
break;
}
*/
}
void IEC101LinkFileSend(struct TIEC101LinkStruct FARDATA *Arg)
{
union WTEMP_ST T;
/* if(Arg->FileLength==0)
{
Arg->TxdCode=0;
*(Arg->TxdBuf ) =0x00;
*(Arg->TxdBuf+1)=0x00;
*(Arg->TxdBuf+2)=01;
*(Arg->TxdBuf+3)=04;
*(Arg->TxdBuf+4)=RTUStatus(Arg);
T.Word=Arg->RxdPacketNo;
*(Arg->TxdBuf+5)=T.B.Low;
*(Arg->TxdBuf+6)=T.B.High;
IEC101LinkSendFrame(Arg);
Arg->TxdPacketNo++;
return;
}
if(Arg->FileLength > IEC101LinkPACKETSIZE) //not the end packet
{
Arg->FileLength -=IEC101LinkPACKETSIZE;
Arg->TxdRepeat=IEC101LinkREPEAT;
*(Arg->TxdBuf ) =(IEC101LinkPACKETSIZE) & 0xFF;
*(Arg->TxdBuf+1)=(IEC101LinkPACKETSIZE) >> 8;
*(Arg->TxdBuf+2)=01;
*(Arg->TxdBuf+3)=02;//Text send
*(Arg->TxdBuf+4)=RTUStatus(Arg);
T.Word=Arg->TxdPacketNo;
*(Arg->TxdBuf+5)=T.B.Low;
*(Arg->TxdBuf+6)=T.B.High;
if(fread(Arg->TxdBuf+7,sizeof(char),IEC101LinkPACKETSIZE,Arg->fp)!=IEC101LinkPACKETSIZE)
{
Nak(Arg,5);
return;
}
IEC101LinkSendFrame(Arg);
Arg->TxdPacketNo++;
}else // Send end packet of a file Send
{
// Arg->TxdPacketNo++;
Arg->TxdRepeat=IEC101LinkREPEAT;
*(Arg->TxdBuf)=(unsigned char)(Arg->FileLength) & 0xFF;
*(Arg->TxdBuf+1)=(unsigned char)(Arg->FileLength) >> 8;
*(Arg->TxdBuf+2)=01;
*(Arg->TxdBuf+3)=04;// end of Text send
*(Arg->TxdBuf+4)=RTUStatus(Arg);
T.Word=Arg->TxdPacketNo;
*(Arg->TxdBuf+5)=T.B.Low;
*(Arg->TxdBuf+6)=T.B.High;
if(fread(Arg->TxdBuf+7,sizeof(char),(size_t)Arg->FileLength,Arg->fp)!=(size_t)Arg->FileLength)
{
Nak(Arg,5);
return;
}
fclose(Arg->fp);
IEC101LinkSendFrame(Arg);
Arg->FileLength =0;
};
*/
}
void IEC101LinkSendFrame(struct TIEC101LinkStruct FARDATA *Arg)
{
int Length;
unsigned int Sum;
unsigned char Count;
unsigned char FARDATA *Frame;
unsigned int Crc;
unsigned int i;
Frame=Arg->TxdBuf;
Length=(*Frame)+(*(Frame+1))*256+7;
Sum=Length;
if(!(*(Arg->TxdBuf+3)&0x80))
{
Crc = 0;
while (--Length >= 0)
{
Crc = (Crc ^ (((int)*(Frame++)) << 8));
for (i = 0; i < 8; ++i)
if (Crc & 0x8000) Crc = ((Crc << 1) ^ 0x1021);
else Crc = Crc << 1;
};
Crc &= 0xFFFF;
*(Arg->TxdBuf+Sum)=Crc;
*(Arg->TxdBuf+Sum+1)=Crc>>8;
}
Sum += 2;
Tputc(Arg->ComTaskNo,1); //01H
ChangeProWarn(Arg->ComTaskNo,1,Sum);
SetTimer(Arg->ComTaskNo,0);
if(Sum >255) Count=255;
else Count=Sum;
Arg->TxdPtr=Count;
Tputs(Arg->ComTaskNo,&Count,(char FARDATA *)Arg->TxdBuf);
Arg->TxdBufLength=Sum;
Arg->TxdPtr -=Count;
if(Arg->TxdBufLength>Arg->TxdPtr) Arg->TxdStatus=SEND;
}