www.pudn.com > rtu.rar > FDK.C
//
// File name =FDK.C //串行通信FDK规约程序
//设计 何风涛
//#include"class.h"
#include"classext.h"
void FdkTask(struct FdkArgStruct *Arg) //FDK规约函数
{
if(TaskStatus(Arg->TaskNo) & 0x02) FdkRxd(Arg); // Rx Task;
if(TaskStatus(Arg->TaskNo) & 0x01) FdkTxd(Arg); // Tx Task;
if(TaskStatus(Arg->TaskNo) & 0x80) FdkTimer(Arg); // Timer Task;
if(TaskStatus(Arg->TaskNo) & 0x40) FdkOverTime(Arg); // Overtime;
if(TaskStatus(Arg->TaskNo) & 0x20) RecLetter(Arg); // Receive Letter;
};
void *InitFdkArgs(int TaskNo)
{
struct FdkArgStruct *Arg;
if((Arg=(struct FdkArgStruct *)malloc(sizeof(struct FdkArgStruct)))==NULL)
{
return(NULL);
}
memset(Arg,0,sizeof(struct FdkArgStruct));
Arg->TaskNo=TaskNo;
Arg->RxdStatus=START;
if((Arg->TxdBuf=(unsigned char *)malloc(1024*sizeof(char)))==NULL)
{
return(NULL);
}
Arg->TxdStatus=WAIT;
Arg->Ykcomm=yknull;
Arg->HSComm=HSnull;
Arg->StatusCode=1;
Arg->Letter_from_box=boxnull;
if((Arg->RxdBuf=(int *)malloc(1024*sizeof(int)))==NULL)
{
return(NULL);
}
if((Arg->RecBuf=(unsigned char *)malloc(1024*sizeof(char)))==NULL)
{
return(NULL);
}
if((Arg->HSBuf=(unsigned char *)malloc(260*sizeof(char)))==NULL)
{
return(NULL);
}
if((Arg->TrnLetter=(unsigned char *)malloc(260*sizeof(char)))==NULL)
{
return(NULL);
}
if((Arg->RecLetter=(unsigned char *)malloc(260*sizeof(char)))==NULL)
{
return(NULL);
}
return(Arg);
};
void FdkRxd(struct FdkArgStruct *Arg)
{
unsigned char c;
if(Arg->RxdStatus==START)
{//SOH
c=(unsigned char)Tgetc(Arg->TaskNo);
if(c!=0x01) //if it's not a start character,clear Rxd buffer;
{
Tgets(Arg->TaskNo,255,Arg->RxdBuf);//清除接收缓冲区
Arg->RxdBufLength=0;
return;
}else
{//接收到开始标志SOH=01H
ChangeProWarn(Arg->TaskNo,0,7);
Arg->RxdStatus=HEAD;
};
};
//---------------Receive head----------------------
if((Arg->RxdStatus==HEAD) && (TaskStatus(Arg->TaskNo) & 0x02))
{
Arg->RxdBufLength=Tgets(Arg->TaskNo,7,Arg->RxdBuf);
if((*(Arg->RxdBuf)==0) && (*(Arg->RxdBuf+1)==0) && (Arg->RxdBufLength==7))
{ //报文长度为零
FdkCommand(Arg);
if(Arg->SetTimeLock!=0xff) SetTimer(Arg->TaskNo,0);
return;
}else
{
Arg->RxdFrameLength=*(Arg->RxdBuf+1)*256+*(Arg->RxdBuf);
if(Arg->RxdFrameLength>=1020)
{
Tgets(Arg->TaskNo,255,Arg->RxdBuf);
Arg->RxdBufLength=0;
Arg->RxdStatus=START;
ChangeProWarn(Arg->TaskNo,0,1);
if(FileError(Arg)) Nak(Arg,1); // Receive Data error
return;
}
if(Arg->RxdFrameLength<=128)
{
ChangeProWarn(Arg->TaskNo,0,Arg->RxdFrameLength+7-Arg->RxdBufLength);
}else
{
ChangeProWarn(Arg->TaskNo,0,128);
}
if(Arg->SetTimeLock!=0xff) SetTimer(Arg->TaskNo,600);
Arg->RxdStatus=FRAME;
};
};
//----------------------------------Receive frame------------------------------------
if((Arg->RxdStatus==FRAME) && (TaskStatus(Arg->TaskNo) & 0x02))
{
if(Arg->RxdFrameLength+7-Arg->RxdBufLength<=128)
{
Arg->RxdBufLength +=Tgets(Arg->TaskNo,Arg->RxdFrameLength+7-Arg->RxdBufLength,(Arg->RxdBuf+Arg->RxdBufLength));
}else
{
Arg->RxdBufLength +=Tgets(Arg->TaskNo,128,(Arg->RxdBuf+Arg->RxdBufLength));
}
if(Arg->RxdBufLength>=(Arg->RxdFrameLength+7))
{
FdkCommand(Arg);
if(Arg->SetTimeLock!=0xff) SetTimer(Arg->TaskNo,0);
return;
};
if(Arg->RxdFrameLength+7-Arg->RxdBufLength<=128)
{
ChangeProWarn(Arg->TaskNo,0,Arg->RxdFrameLength-Arg->RxdBufLength+7);
}else
{
ChangeProWarn(Arg->TaskNo,0,128);
}
if(Arg->SetTimeLock!=0xff) SetTimer(Arg->TaskNo,500);
return;
};
};
void FdkTxd(struct FdkArgStruct *Arg) //将组装好的帧发送到串口发送缓冲区
{
unsigned char Num,OldNum;
if(Arg->TxdStatus==WAIT)
{
StopTxd(Arg->TaskNo);
return;
};
if((Arg->TxdBufLength - Arg->TxdPtr) <= 255) Num=Arg->TxdBufLength-Arg->TxdPtr;
else Num=255;
OldNum=Num;
Tputs(Arg->TaskNo,&Num,(char *)(Arg->TxdBuf+Arg->TxdPtr));
Arg->TxdPtr+=OldNum-Num;
if(Arg->TxdBufLength<=Arg->TxdPtr) Arg->TxdStatus=WAIT;
};
void FdkTimer(struct FdkArgStruct *Arg)
{//定时到
int i,j;
ResetTimer(Arg->TaskNo);
if(Arg->SetTimeLock==0xff)
{
LetterOper(Arg);
return;
}
Tgets(Arg->TaskNo,255,Arg->RxdBuf+7);
Arg->RxdBufLength=0;
Arg->RxdStatus=START;
ResetCom(Arg->TaskNo);
ChangeProWarn(Arg->TaskNo,0,1);
ChangeProWarn(Arg->TaskNo,1,1);
Nak(Arg,6); // Receive Data error
SetTimer(Arg->TaskNo,0);
return;
};
void FdkOverTime(struct FdkArgStruct *Arg)
{//超时到
ResetWait(Arg->TaskNo);
Arg->HSComm=HSnull;
Arg->Ykcomm=yknull;
Arg->SetTimeLock=0;
SetTimer(Arg->TaskNo,0); //add by yzd 11/8
if(Arg->Ykcomm==waitproof) YkNak(Arg);
else Nak(Arg,9);
};
void RecLetter(struct FdkArgStruct *Arg)
{
}
void FdkCommand(struct FdkArgStruct *Arg)
{
unsigned int i;
if(Arg->RxdBufLength>1024)
{//清接收缓冲区
Tgets(Arg->TaskNo, 255, Arg->RxdBuf);
Arg->RxdBufLength=0;
Arg->RxdStatus=START;
ChangeProWarn(Arg->TaskNo,0,1);
if(FileError(Arg)) Nak(Arg,1); // Receive Data error
return;
}
if(!RxdCrc(Arg)) // if CRC check error,clear RXD buffer;
{
Tgets(Arg->TaskNo,255,Arg->RxdBuf);
Arg->RxdBufLength=0;
Arg->RxdStatus=START;
ChangeProWarn(Arg->TaskNo,0,1);
if(FileError(Arg)) Nak(Arg,0x1); // Receive Data error
}else FdkComTrans(Arg);
ChangeProWarn(Arg->TaskNo,0,1);
Arg->RxdStatus=START;
};
//////////////////////////////////////////////////////////////////////////////
char RxdCrc(struct FdkArgStruct *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 *)Arg->RecBuf,Length);
if(i==(*(Arg->RecBuf+Length+1)*256+*(Arg->RecBuf+Length))) return(0xff);
else return(0);
};
unsigned int Crc16(unsigned char *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 Ack(struct FdkArgStruct *Arg)//对无需应答帧的确认
{
*(Arg->TxdBuf)=0;
*(Arg->TxdBuf+1)=0;
*(Arg->TxdBuf+2)=0x06;
*(Arg->TxdBuf+3)=00;
*(Arg->TxdBuf+4)=RTUStatus(Arg);
FdkSendAFrame(Arg);
}
void Nak(struct FdkArgStruct *Arg,unsigned char NakNo)//对接收错误帧的 回执
{
//define NakNo as 0:voilable command,1:Crc error,2:voilable PacketNo,3:File Error
*(Arg->TxdBuf)=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);
FdkSendAFrame(Arg);
};
////////////////////////////////////////////////////////////////////////////
void FdkSendAFrame(struct FdkArgStruct *Arg)
{
int Length;
unsigned int Sum;
unsigned char Count;
unsigned char *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->TaskNo,01);
if(Sum >255)
Count=255;
else
Count=Sum;
Arg->TxdPtr=Count;
Tputs(Arg->TaskNo,&Count,(char *)Arg->TxdBuf);
Arg->TxdBufLength=Sum;
Arg->TxdPtr -=Count;
if(Arg->TxdBufLength > Arg->TxdPtr)
Arg->TxdStatus=SEND;
};
void FdkComTrans(struct FdkArgStruct *Arg)
{
unsigned char i,m,k;
unsigned kk, offset,j;
/* if(*(Arg->RecBuf+4) & 0x02)
{
for(j=0;jYCDNUM;j++)
{
Arg->MYC[Arg->YCDNO[j]]=Arg->MYCtemp[j];
}
}
if(*(Arg->RecBuf+4)&0x80)
{
*(Arg->TxdBuf+3)|=0x80;
FdkSendAFrame(Arg);
return;
} */
switch(*(Arg->RecBuf+2)) //功能码
{
case 1: FdkRecFile(Arg); //文件传送
break;
case 2: Arg->TxdCode=0; //YC查询
yc(Arg);
break;
case 3: Arg->TxdCode=0; //YX查询
yx(Arg);
break;
case 4: Arg->TxdCode=0;
kwh(Arg); //电度查询
break;
case 5: Arg->TxdCode=0;
sjjl(Arg); //事项记录查询
break;
case 6: FdkAck(Arg); //无须应答帧确认
break;
case 7: //trnsmit system status to notebook //系统状态
Arg->TxdCode=0;
Sysst(Arg);
break;
case 8: //yk operate 遥控操作
Arg->TxdCode=0;
Yk(Arg);
break;
case 10: Arg->TxdCode=0; //高速采样
HighSpeedColl(Arg);
break;
case 11: //reset //系统复位
Arg->TxdCode=0;
SysReset();
break;
case 15: //transparent data 透明数据传送
Arg->TxdCode=0;
TransData(Arg);
break;
case 16: Arg->TxdCode=0; //时间
arsktime(Arg);
break;
case 17: Arg->TxdCode=0; //变量查询
trnvari(Arg);
break;
case 18: Arg->TxdCode=0; //故障录波
trojl(Arg);
break;
case 21: FdkNak(Arg); //接收错误帧的回执
break;
case 22: //make system config file 配置系统文件
Ack(Arg);
if(!RemoteConfig()) Nak(Arg,0);
break;
case 30: //complex data packet 召唤全数据
break;
case 31: //召唤变化数据报文
break;
default : if(FileError(Arg)) Nak(Arg,0);
break;
};
}
void trojl(struct FdkArgStruct *Arg)
{ //故障录波
}
void HighSpeedColl(struct FdkArgStruct *Arg)
{ //高速采样
};
void HSDataTrn(struct FdkArgStruct *Arg)//应答采样数据High Speed 数据传送
{
}
////////////////////////////////////////////////////////////////////////////////
void Yk(struct FdkArgStruct *Arg)
{// 遥控操作
}
void Sysst(struct FdkArgStruct *Arg)
{ //系统状态
}
void yc(struct FdkArgStruct *Arg)
{ //YC查询
}
void yx(struct FdkArgStruct *Arg)
{//YX查询
}
//////////////////////////////////////////////////////////////////////////////
void FdkRecFile(struct FdkArgStruct *Arg) //正文传送1H
{
unsigned int i;
char command[64];
switch(*(Arg->RecBuf+3)) //文件方式扩展码
{
case 0: //下装文件(以写的方式打开文件)
command[0]='\0';
strcpy(Arg->RecName,(char *)(Arg->RecBuf+5));
if(strncmpi((char *)(Arg->RecBuf+5),"outfile.x1a",11)==0)
{
Arg->WriFlag=0xff;
strcpy(command,"e:");
}
strcat(command,Arg->RecName);
fclose(Arg->fp);
if((Arg->fp=fopen(command, "wb"))== NULL)
{
// Send File Nak for file open error
Nak(Arg,3);
Arg->RxdCode=NOUSE;
Arg->RxdExtCode=NOUSE;
}else
{
// Send File Ack for file open OK with write mode;
i=strncmpi((char *)(Arg->RecBuf+5),"sta",3);
if(i==0)
{
*(Arg->RecBuf+0xb)=0;
Arg->STANo=atoi((char *)(Arg->RecBuf+8));
}
Ack(Arg);
Arg->RxdPacketNo=0;
Arg->FileLength=0;
for(i=37;i>=33;i--)
{
Arg->FileLength <<=8;
Arg->FileLength +=*(Arg->RecBuf+i);
};
};
break;
case 1: //上装文件 FdkROpenF(struct FdkArgStruct *Arg);
fclose(Arg->fp);
if ((Arg->fp=fopen((char *)(Arg->RecBuf+5), "rb"))== NULL)
{
Nak(Arg,3);
Arg->RxdCode=NOUSE;
Arg->RxdExtCode=NOUSE;
}else
{
// Send File 01/02 for file open OK with read mode;
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;
Arg->TxdExtCode=1;
#ifdef NOTEPR
printf("***%lx**",Arg->FileLength);
#endif
FdkAck(Arg);
};
break;
case 02://正文传送----Receive Text(struct FdkArgStruct *Arg);
if(*(Arg->RecBuf+5) == (Arg->RxdPacketNo-1))
{
Ack(Arg);
break;
}
if(*(Arg->RecBuf+5) != Arg->RxdPacketNo)
{
Nak(Arg,2);
#ifdef NOTEPR
printf(" Packet No Error \n");
#endif
break;
};
Arg->RxdPacketLength=*(Arg->RecBuf)+*(Arg->RecBuf+1)*256-1;
fwrite(Arg->RecBuf+6,sizeof(char),Arg->RxdPacketLength,Arg->fp);
Arg->FileLength -=Arg->RxdPacketLength;
Arg->RxdPacketNo++;
#ifdef NOTEPR
printf(" Receive a Text packet \n");
#endif
Ack(Arg);
break;
case 4://正文传送结束 SendEot(Struct FdkArgStruct *Arg);
if(*(Arg->RecBuf+5) != Arg->RxdPacketNo)
{
Nak(Arg,2);
#ifdef NOTEPR
printf(" Packet No Error \n");
#endif
break;
};
Arg->RxdPacketLength=*(Arg->RecBuf)+*(Arg->RecBuf+1)*256-1;
fwrite(Arg->RecBuf+6,sizeof(char),Arg->RxdPacketLength,Arg->fp);
Arg->FileLength -=Arg->RxdPacketLength;
fclose(Arg->fp);
Arg->RxdCode=0; //nouse;
#ifdef NOTEPR
printf(" Receive a end of file end packet \n");
#endif
if(Arg->FileLength==0)
{
if(Arg->STANo!=0)
{
DBRNStatus[PHDLCImage[Arg->STANo*2].LogNo].NeedWhat|=0x0010;
DBRNStatus[PHDLCImage[Arg->STANo*2].LogNo].Mask|=0x0018;
#ifdef NOTEPR
cprintf("set sta*.* flag");
#endif
}
Arg->STANo=0;
if((Arg->WriFlag==0xff)&&(strncmpi(Arg->RecName,"outfile.x1a",11)==0)){
setdisk('e'-'a');
Arg->WriFlag=0;
Ack(Arg);
delay(3000);
if(!WriteEEProm())
Nak(Arg,3);
}
else{
Arg->WriFlag=0;
Ack(Arg);
}
}
else Nak(Arg,3);
break;
case 8: //
if(unlink((char *)(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 FdkArgStruct *Arg)
{
if(Arg->TxdCode !=0)
{
Arg->TxdRepeat--;
if((Arg->TxdRepeat)) //error! Retry for >TxdRepeat times
{
*(Arg->TxdBuf+3)|=0x80;
FdkSendAFrame(Arg);
}else
{// error! Alaready Retry for ten times
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);
FdkSendAFrame(Arg);
}
}
return(0);
}
return(0xff);
}
void FdkNak(struct FdkArgStruct *Arg)//接收错误帧的回执
{
if(Arg->TxdCode !=0)
{
Arg->TxdRepeat--;
if((Arg->TxdRepeat))//重传 error! Retry
{
*(Arg->TxdBuf+3)|=0x80;
FdkSendAFrame(Arg);
}else//不再重传 error! Alaready Retry for ten times
{
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);
FdkSendAFrame(Arg);
}
}
}else
{// error! Retry for Arg->TxdRepeat times
*(Arg->TxdBuf+3)|=0x80;
FdkSendAFrame(Arg);
}
};
////////////////////////////////////////////////////////////////////////////////
void FdkAck(struct FdkArgStruct *Arg)//无须应答帧确认
{
int i;
switch(Arg->TxdCode)
{
case 0:// the Last Send Task complate
break;
case 1://文件传送
if(Arg->TxdExtCode==04)//正文传送结束 File Send Process Complate
{
Arg->TxdCode=0;
return;
};
if(Arg->FileLength==0)
{//File Send OK!
Arg->TxdCode=0;
return;
};
if(Arg->FileLength > PACKETSIZE) //not the end packet
{
Arg->FileLength -=PACKETSIZE;
Arg->TxdRepeat=REPEAT;
*(Arg->TxdBuf ) =(PACKETSIZE+1) & 0xFF;
*(Arg->TxdBuf+1)=(PACKETSIZE+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),PACKETSIZE,Arg->fp)!=PACKETSIZE)
{
Nak(Arg,5);
return;
}
FdkSendAFrame(Arg);
Arg->TxdPacketNo++;
}else // Send end packet of a file Send
{
Arg->TxdRepeat=REPEAT;
*(Arg->TxdBuf ) =(Arg->FileLength+1) & 0xFF;
*(Arg->TxdBuf+1)=(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),Arg->FileLength,Arg->fp)!=Arg->FileLength)
{
Nak(Arg,5);
return;
}
fclose(Arg->fp);
FdkSendAFrame(Arg);
Arg->FileLength =0;
};
break;
};
};
void kwh(struct FdkArgStruct *Arg) //电度查询04H
{
}
void sjjl(struct FdkArgStruct *Arg) //事项记录查询5H
{
}
void arsktime(struct FdkArgStruct *Arg)
{
}
void writetime(struct FdkArgStruct *Arg)
{
}
unsigned char readtime(unsigned char *p)
{
}
void trnvari(struct FdkArgStruct *Arg)//变量查询
{
}
void *MakeTable(void) //索引表
{
}
void TransData(struct FdkArgStruct *Arg) //透明数据传送15H
{
}