⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmodemr.c

📁 xmodem协议接收程序
💻 C
字号:
#include "mcudslbase.h"#include "timer.h"#include "serio.h"#include "crctab.h"/* * Copyright (c) 1995 by Edward A. Falk *//********** * * *	@   @  @   @   @@@   @@@@   @@@@@  @   @  @@@@    *	 @ @   @@ @@  @   @  @   @  @      @@ @@  @   @   *	  @    @ @ @  @   @  @   @  @@@    @ @ @  @@@@    *	 @ @   @ @ @  @   @  @   @  @      @ @ @  @  @    *	@   @  @ @ @   @@@   @@@@   @@@@@  @ @ @  @   @   * *	XMODEMR - receiver side of xmodem/ymodem protocol * *	Caller sets flags defined in xmodem.h as appropriate. *	(default is basic xmodem) * *	This code is designed to be called from inside a larger *	program, so it is implemented as a state machine where *	practical. * * *	functions: * *	XmodemRInit( INT8U *BaseAddr, Protocol p) *		Initiate a receive * *	XmodemRTimeout() *		called after timeout expired * *	XmodemRRcv(char c) *		called after character received * *	XmodemRAbort() *		abort transfer * *	all functions return 0 on success, 1 on abort * * * *	Edward A. Falk * *	January, 1995 * * * **********/#include "xmodem.h"	/* TODO: WXmodem */	bool	xmodem1k = False ;	Protocol protocol = Xmodem ;	int	xmTfd = -1 ;	int	xmRfd = -1 ;	int	xmTimeout = 0 ;typedef	enum {	  Start,	/* waiting to begin */	  Init,		/* sent initial NAK, 'C' or 'W' */	  Packet,	/* receiving a packet */	  Wait,		/* wait for start of next packet */	} XmodemState ;static INT8U * memAddr;static	bool		ymodem ;static	XmodemState	state = Start ;static	int		errorCount = 0 ;static	int		errorCount2 ;static	int		ignoreCount ;static	int		eotCount ;	/* count EOT's, reject first one */static	int		inCount ;	/* characters received this packet */static	int		pktLen ;	/* length of this packet data */static	int		pktHdrLen ;	/* id, cmpl, checksum or crc */static	char		packet[MAXPACKET+5], *optr ;static	int		packetId ;	/* id of last received packet */static	int		packetCount ;	/* # packets received *//*static	FILE		*ofile ;	 output file fd static	int		fileLen, fileDate, fileMode ;*/static	int	XmodemRStart() ;static	int	processPacket() ;static	int	rejectPacket() ;static	int	acceptPacket() ;int XmodemRInit( INT8U *BaseAddr, Protocol prot ){	int	err ;	memAddr=(INT8U*)BaseAddr;	state = Start ;	protocol = prot ;	ymodem =( (prot == Ymodem) || (prot == YmodemG) );	eotCount = errorCount = errorCount2 = 0 ;	err=XmodemRStart();	if( err!=0 )	  return err ;	state = Init ;	packetId = ymodem ? 255 : 0 ;	packetCount = 0 ;	pktHdrLen = protocol == Xmodem ? 3 : 4 ;	return 0 ;}	/* send startup character */static	intXmodemRStart(){static	char	pchars[5] = {NAK,'C','W','C','C'} ;static	int	timeouts[5] = {INITTO, INITTO2, INITTO2, INITTO, INITTO} ;	char	c = pchars[(int)protocol] ;	int	err ;	err=sendFlush(c);	if( err!=0 )	  return err ;	xmTimeout = timeouts[((int)protocol)] ;	return 0 ;}intXmodemRRcv(char c){	errorCount = 0 ;	switch( state ) {	  case Start:		/* shouldn't happen, ignore */	    if( c == CAN )	      return XmErrCancel ;	    break ;	  case Init:		/* waiting */	  case Wait:	    switch( c ) {	      case SOH:	      case STX:		pktLen = c == STX ? 1024 : 128 ;		inCount = 0 ;		optr = packet ;		state = Packet ;		xmTimeout = PKTTO ;		break ;	      case EOT:		if( ++eotCount > 1 ) {		  sendFlush(ACK) ;		  if( ymodem )		    return 0;/*XmodemRInit() ;	 restart protocol */		  else		    return XmDone ;		}		else		  return rejectPacket() ;	/* make xmitter try again */	      case CAN: return XmErrCancel ;	      default:		/* ignore all others */		if( ++ignoreCount > 1030 ) {		  ignoreCount = 0 ;		  return sendFlush(NAK) ;		}		break ;	    }	    break ;	  case Packet:		/* mid packet */	    *optr++ = c ;	    if( ++inCount >= pktLen + pktHdrLen )	      processPacket() ;	    break ;	}	return 0 ;}intXmodemRTimeout(){	if( ++errorCount > MAXERROR )	  return state == Init ? XmErrInitTo : XmErrRcvTo ;	switch( state ) {	  case Start: return -1 ;		/* shouldn't happen */	  case Init:	    if( ++errorCount2 >= 3 )	      switch( protocol ) {		case WXmodem: protocol = XmodemCrc ; errorCount2 = 0 ; break ;		case XmodemCrc: protocol = Xmodem ; pktHdrLen = 3 ; break ;	      }	    return XmodemRStart() ;	  case Wait:			/* timeout while waiting */	  case Packet:			/* timeout in mid packet */	    return rejectPacket() ;	}	return -1;}intXmodemRAbort(){	  return sendCancel() ;}static	intprocessPacket(){	int	id = (INT8U)packet[0] ;	int	idc = (INT8U)packet[1] ;	int	i ;	if( idc != 255-id )	  return rejectPacket() ;	if( id == packetId )		/* duplicate */	  return acceptPacket() ;	if( id != (packetId+1)%256 ) {	/* out of sequence */	  (void) sendCancel() ;	  return XmErrSequence ;	}	if( protocol == Xmodem )	{	  /* compute checksum */	  register int csum = calcChecksum(packet+2, pktLen) ;	  if( csum != (INT8U) packet[2+pktLen] )	    return rejectPacket() ;	}	else	{	  unsigned short crc0 = (INT8U)packet[pktLen+2] << 8 | (INT8U)packet[pktLen+3] ;	  unsigned short crc1 = calcrc(packet+2, pktLen) ;	  if( crc0 != crc1 )	    return rejectPacket() ;	}	/* it's a good packet */	packetId = (packetId+1)%256 ;	/* is this the first packet? */	if( packetCount == 0 )	{	  if( ymodem )	  {	    if( packet[2] == '\0' )	/* last file */	    {	      (void) acceptPacket() ;	      return XmDone ;	    }	    /*if( packet[2] == '/' )	      strcpy(xmFilename, packet+2) ;	    else {	      strcpy(xmFilename, xmDefPath) ;	      strcat(xmFilename, packet+2) ;	    }	    fileLen = fileDate = fileMode = -1 ;	    sscanf(packet+2+strlen(packet)+1, "%d %o %o",		&fileLen, &fileDate, &fileMode) ;*/	  }	  /*if( (ofile = fopen(xmFilename, "w")) == NULL ) {	    sendCancel() ;	    return XmErrCantOpen ;	  }*/	  if( ymodem ) {	    packetCount = 1 ;	    acceptPacket() ;	    return sendFlush('C') ;	  }	  else	    state = Packet ;	}	++packetCount ;	for(i=0;i<pktLen;i++)	{	  memAddr[i]=packet[i+2];	}	memAddr+=pktLen;	return acceptPacket() ;	/* TODO: ymodem: if this is last packet, truncate it */	/*if( (i=fwrite(packet+2, 1, pktLen, ofile)) != pktLen )	{	  sendCancel() ;	  return XmErrSys ;	}	else	  return acceptPacket() ;*/}static	intrejectPacket(){	state = Wait ;	xmTimeout = INITTO ;	return sendFlush(NAK) ;}static	intacceptPacket(){	state = Wait ;	xmTimeout = INITTO ;	return sendFlush(ACK) ;}intsendCancel(){	return sendFlush(CAN) || sendFlush(CAN) ;}	/* send one character, return nonzero on error */intsendFlush(char c){	/* first, flush input port */	/* TODO: caller provide a way to do this? */	/* TODO: caller provides flush 	if( ioctl(xmRfd, TCFLSH, TCIFLUSH) == -1 )	  return XmErrSys ;*/	return sendChr(c) ;}	/* send one character, return nonzero on error */intsendChr(char c){	/* TODO: caller provide character output func? */	outbyte(c);	return 0;	//return write(xmTfd, &c, 1) ==1 ? 0 : XmErrSys ;}/* send some character, return nonzero on error */intsendStr(char *str, int len){	/* TODO: caller provide character output func? */	INT32S i=0;		for(i=0;i<len;i++)       sendChr(*str++);	return 0 ;}intcalcChecksum(char *ptr, int count){	register int csum = 0 ;	while( --count >= 0 )	  csum += (INT8U) *ptr++ ;	return csum & 255 ;}INT32U receive(INT8U * BaseAddr){    TIMER timeout;	INT32U	done = FALSE ;    	INT8U	i ;	//INT32S	len ;	settimer(&timeout,xmTimeout*1000);	xmodem1k = 0 ;	done = XmodemRInit( ((INT8U*)BaseAddr), XmodemCrc) != 0 ;#ifdef	COMMENT//	xmodem1k = 1 ;//	done = XmodemRInit("./", Ymodem) != 0 ;#endif	/* COMMENT */	while(!done)	{	  	  INT32U tmOut=FALSE;	  i=inbyte_time(xmTimeout*1000,&tmOut);	  	  	  if( tmOut==TRUE )	    done = XmodemRTimeout() != 0 ;	  else {	      done = XmodemRRcv(i) != 0 ;	  }	  	}	if(pktLen == 128)	return (packetCount<<7);	else if(pktLen == 1024)	return (packetCount<<10); 	else	return (packetCount*pktLen); }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -