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; 
}