#include "ymodem.h"
/***************************************************************************/
unsigned int count_read=0; /*the bytes of datas received from buffer. count from every packet begin*/
unsigned char PacketStartFlagRecv=1;/*indicate one packet begin*/
unsigned int PacketLen=0;
unsigned char blknum_cur=0;//当前数据包编号
char rxdata[1029]; /* An 8-bit integerthat is not signed.*/
char first_flag=1; /*it should be set to 1 every time when a file ready to transfer*/
FILE* fp_recv=NULL;
char* filename;
char filename_change=0;
unsigned int BlockLength;
unsigned int RealLen=0; /*FileLen:record the file length left if this field in the first block*/
/*ReaLen: the real block length barring pads in the last block*/
char* get_name(unsigned char* rec_buf);
void get_length(unsigned int name_len,unsigned char* rec_buf);
int procheader(unsigned char* rec_buf);
int procrecdata(unsigned char* rec_buf);
int control_recv(char* device)
{
int head_check;
int file_check;
int i;
int len;
int CAN_CNT=0;
char bt;
char test=1;
bt='C';
CrcFlag=1; //bt="C":meant CRC check 全局变量
if((fd=_open(device, _O_RDWR|_O_BINARY|_O_NONBLOCK ))==-1)//打开串口
return(COM_OPEN_ERR);
count_read=0;//统计收到的字节数
/*进入死循环,向发送方发送一个C*/
for(;;)
{
delay(10000000);
if(_write(fd, &bt,1)==-1) //request sender to send file with CRC check 写失败返回错误码,关闭串口
{
printf("write err!\n");
_close(fd);
return(COM_WRITE_ERR);
}
for(i=0;i<0x1fffff;i++)//如果发送C成功,延时后
delay(0xffffffff);
if((len=_read(fd,rxdata+count_read,1))==-1)//准备接受发送方发送的第一个包
{
if(errno==EAGAIN)
{
if(test)
{
test=0;
printf("waiting...............\n");
}
continue;
}
_close(fd);
return(COM_READ_ERR);
}
if(len)
{
#ifdef DEBUG
printf("%x\n",rxdata[0]);
#endif
count_read+=len;//把收到的字节数加到统计字节数中去
break;
}
}
while(1)
{
if((len=_read(fd,rxdata+count_read,1))==-1)
{
if(errno==EAGAIN)
{
continue;
}
printf("read fail!we have read %d bytes\n",count_read);
return(COM_READ_ERR);
}
else
{
count_read+=len;
}
if(count_read) //如果正确收到包
{
if(PacketStartFlagRecv)
{
PacketStartFlagRecv=0;
/*第一帧的第一个字节*/
switch(rxdata[0])
{
case SOH:
if(CAN_CNT)
CAN_CNT=0;
#ifdef DEBUG
printf("SOH!128 bytes per packet!\n");
#endif
PacketLen=133; //CRC check :128+5
BlockLength=128;
break;
case STX:
if(CAN_CNT)
CAN_CNT=0;
#ifdef DEBUG
printf("STX!1024 bytes per packet!\n");
#endif
PacketLen=1029; //case CRC check
BlockLength=1024;
break;
case EOT:
{
if(CAN_CNT)
CAN_CNT=0;
#ifdef DEBUG
printf("get EOT!\n");
#endif
printf("file has been completly transfered!\n");
if(filename_change)
{
filename_change=0;
printf("File existed! Save it as %s \n",filename);
}
printf("File length: %dbytes\n",FileLenBkup);
if(*filename!=(char)NULL)
{
free(filename);
*filename=(char)NULL;
}
RealLen=0;
FileLen=0;
PacketLen=0;
count_read=0;
blknum_cur=0;
PacketStartFlagRecv=1;
first_flag=1; //wait for next file
bt=(char)ACK; // "ACK":config the file end
if(_write(fd,&bt,1)==-1)
{
_close(fd);
return(COM_WRITE_ERR);
}
bt='C'; //request continue transmission with CRC check
if(_write(fd, &bt,1)==-1) //request sender to send file with CRC check
{
_close(fd);
return(COM_WRITE_ERR);
}
break;
}
case CAN:
CAN_CNT++;
count_read=0;
PacketStartFlagRecv=1;
break;
default:
{
if(CAN_CNT)
CAN_CNT=0;
printf("unvalid packet head,retry!the first data is:0x%x\n",rxdata[0]);
PacketStartFlagRecv=1;
count_read=0;
bt=(char)NAK; // "NAK":indicate retransmission
if(_write(fd, &bt,1)==-1) //request sender to send file with CRC check
{
printf("write fail!\n");
_close(fd);
return(COM_WRITE_ERR);
}
}
}
}
}
if(CAN_CNT==2)
{
printf("transmittion is canceled by user!\n");
if(*filename!=(char)NULL)
remove(filename);
_close(fd);
exit(0);
}
if(!count_read) //get EOT or unvilid packet head or CAN
continue;
if(count_read==PacketLen)
{
#ifdef DEBUG
printf("get a packet completly!count_read:%d\n",count_read);
#endif
PacketStartFlagRecv=1;
count_read=0;
head_check=procheader((unsigned char *)rxdata);//包头检查
switch(head_check)
{
case HEAD_OK:
#ifdef DEBUG
printf("head check OK!\n");
#endif
file_check=procrecdata((unsigned char *)rxdata);//文件数据区检查
switch(file_check)
{
case FILE_OPEN_ERR:
#ifdef DEBUG
printf("ERROR occured when open the file!\n");
#endif
if(first_flag)
{
bt=(char)NAK; //filename packet .retrans if error occured
if(_write(fd, &bt,1)==-1) //request the sender to send file with CRC check
{
_close(fd);
return(COM_WRITE_ERR);
}
}
else
{
bt=(char)CAN;
if(_write(fd, &bt,1)==-1) //request sender to send file with CRC check
{
_close(fd);
return(COM_WRITE_ERR);
}
if(_write(fd, &bt,1)==-1) //request sender to send file with CRC check
{
_close(fd);
return(COM_WRITE_ERR);
}
delay(10000000);
_close(fd);
exit(0);
}
case NO_MORE_FILE:
#ifdef DEBUG
printf("Files have been transfered completly\n");
#endif
bt=(char)ACK; //加入发送编辑框对应字符串 "ACK";确认结束
if(_write(fd, &bt,1)==-1) //request sender to send file with CRC check
{
_close(fd);
return(COM_WRITE_ERR);
}
delay(10000000);
_close(fd);
exit(0);
default:
#ifdef DEBUG
printf("continue next packet.....\n");
#endif
bt=(char)ACK; //加入发送编辑框对应字符串 "ACK",指示继续
if(_write(fd, &bt,1)==-1) //request sender to send file with CRC check
{
_close(fd);
return(COM_WRITE_ERR);
}
if(first_flag)
{
bt='C'; //加入发送编辑框对应字符串 "C";指示以CRC检测的方式发送文件内容
if(_write(fd, &bt,1)==-1) //request sender to send file with CRC check
{
_close(fd);
return(COM_WRITE_ERR);
}
}
}
break;
case FORMAT_UNSUPPORT:
#ifdef DEBUG
printf("ERROR! Unsupported Format!\n");
#endif
if(first_flag)
{
bt=(char)NAK; //文件名数据包,出错指示重发
if(_write(fd, &bt,1)==-1) //request sender to send file with CRC check
{
_close(fd);
return(COM_WRITE_ERR);
}
}
else
{
bt=(char)CAN; //加入发送编辑框对应字符串 "CAN";指示结束
if(_write(fd, &bt,1)==-1) //request sender to send file with CRC check
{
_close(fd);
return(COM_WRITE_ERR);
}
if(_write(fd, &bt,1)==-1) //request sender to send file with CRC check
{
_close(fd);
return(COM_WRITE_ERR);
}
_close(fd);
exit(FORMAT_UNSUPPORT);
}
break;
case CRC_ERR:
#ifdef DEBUG
printf("CRC ERROR!\n");
#endif
case BLK_REPEAT:
#ifdef DEBUG
printf("ERROR! Blocks repeat!\n");
#endif
bt=(char)NAK; //加入发送编辑框对应字�
评论10