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

📄 zmodem.c

📁 本source code 為s3c4510的bootloader
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lintstatic const char rcsid[] = "$Id: zmodem.c,v 1.1.1.1 2001/03/08 00:01:48 efalk Exp $" ;#endif/* * Copyright (c) 1995 by Edward A. Falk *//********** * * *	@@@@@  @   @   @@@   @@@@   @@@@@  @   @   *	   @   @@ @@  @   @  @   @  @      @@ @@   *	  @    @ @ @  @   @  @   @  @@@    @ @ @   *	 @     @ @ @  @   @  @   @  @      @ @ @   *	@@@@@  @ @ @   @@@   @@@@   @@@@@  @ @ @   * *	ZMODEM - main logic parser for zmodem library * * *	Routines provided here: * * *	name (args) *		Brief description. * *	int ZmRcv(u_char *buffer, int len, ZModem *info) *		Call whenever characters are received.  If this function *		returns ZmDone, previous function has completed successfully, *		either call ZmTFile() to start next file, or call *		ZmTFinish() to terminate the session. * * *	int *	ZmTimeout(ZModem *info) *		Call whenever the timeout period expires and no *		characters have been received. * *	int *	ZmAttention(ZModem *info) *		Call whenever the attention sequence has been received *		from the remote end.  It is safe to call this function *		from an interrupt handler. * *	int *	ZmAbort(ZModem *info) *		Call to abort transfer.  Physical connection remains *		open until you close it. * * * * *	Edward A. Falk * *	January, 1995 * * * **********//* TODO: sample input before initial send *//* TODO: more intelligent timeout dispatch *//* TODO: read all pending input before sending next data packet out *//* TODO: if received ZDATA while waiting for ZFILE/ZFIN, it's probably	leftovers *//* TODO: enable flow control for zmodem, disable for X/YModem */#include "zmodem.h"#include "crctab.h"static	u_char	ZmZeros[4] = {0,0,0,0} ;// static function definition ////////////////////////////////////////////////static int ZmIdleChar(u_char c, ZModem *info);static u_int ZmRcvHex( u_int i, char c );static int ZmHdrChar( u_char c, ZModem *info );static int ZmDataChar( u_char c, ZModem *info );static int ZmFinishChar( char c, ZModem *info );static int ZmProtocol( ZModem *info );static int ZmDataReceived( ZModem *info, int crcGood );static int ZmGotCommandData( ZModem *info );static int ZmGotStderrData( ZModem *info);/* LEXICAL BOX: handle characters received from remote end. * These may be header, data or noise. * * This section is a finite state machine for parsing headers * and reading input data.  The info->chrCount field is effectively * the state variable. */int ZmRcv( u_char *str, int len, ZModem *info ){ u_char	c ;	int	err ;	info->rcvlen = len ;	while( --info->rcvlen >= 0 )	{	  c = *str++ ;	  if( c == CAN ) {	    if( ++info->canCount >= 5 ) {	      ZStatus(RmtCancel, 0, NULL) ;	      return ZmErrCancel ;	    }	  }	  else	    info->canCount = 0 ;	  if( info->InputState == Ysend ) 	   {            err = YsendChar(c, info);	    if(err) return(err);	   }	  else 	  if( info->InputState == Yrcv ) 	   {            err = YrcvChar(c, info);	    if(err) return(err);	   }	  else if( c != XON && c != XOFF )	  {	    /* now look at what we have */	    switch( info->InputState )	    {	      case Idle:                err = ZmIdleChar(c, info);		if(err) return(err);		break ;	      case Inhdr:                err = ZmHdrChar(c, info);		if(err) return(err);		break;	      case Indata:		err = ZmDataChar(c, info);		if(err) return(err);		break ;	      case Finish:                err = ZmFinishChar(c, info);		if(err) return(err);		break ;	      default:		break ;	    }	  }	}	return(0);}/* handle character input while idling * looking for ZPAD-ZDLE sequence which introduces a header */static	int ZmIdleChar(u_char c, ZModem *info){	if( info->chrCount == 0 )	{	  if( c == ZPAD )	    ++info->chrCount ;	  else if( info->state == Sending  &&  ++info->noiseCount > MaxNoise )	    info->waitflag = 1 ;	  else if( info->state == TStart && (c == 'C' || c == 'G' || c == NAK) )	  {	    /* switch to ymodem */	    info->state = YTStart;	    info->InputState = Ysend;	    info->Protocol = YMODEM;	    return YsendChar(c, info) ;	  }	  else	    ZIdleStr(&c, 1, info) ;	}	else	{	  switch( c ) {	    case ZPAD:	      ++info->chrCount ;	      break ;	    case ZDLE:	      info->InputState = Inhdr;	      info->chrCount=0 ;	      break ;	    default:	      while( --info->chrCount >= 0 )		ZIdleStr((u_char *)"*", 1, info) ;	      info->chrCount = 0 ;	      break ;	  }	}	return 0 ;}static	u_int ZmRcvHex( u_int i, char c ){	if( c <= '9' )	  c -= '0' ;	else if( c <= 'F' )	  c -= 'A'-10 ;	else	  c -= 'a'-10 ;	return (i<<4)+c ;}	/* handle character input in a header */static	int ZmHdrChar( u_char c, ZModem *info ){	int	i ;	int	crc=0 ;	if( c == ZDLE ) {	  info->escape = 1 ;	  return 0 ;	}	if( info->escape ) {	  info->escape = 0 ;	  switch( c ) {	    case ZRUB0: c = 0177 ; break ;	    case ZRUB1: c = 0377 ; break ;	    default: c ^= 0100 ; break ;	  }	}	if( info->chrCount == 0 ) {	/* waiting for format */	  switch( c ) {	    case ZHEX:	    case ZBIN:	    case ZBIN32:	      info->DataType = c ;	      info->chrCount = 1 ;	      info->crc = (info->DataType != ZBIN32) ? 0 : 0xffffffffL ;              {               int pos;               for(pos = 0; pos < sizeof(info->hdrData); ++pos)	        {	         info->hdrData[pos] = 0;                }	      }	      break ;	    default:	      info->InputState = Idle;	      info->chrCount = 0 ;	      return ZXmitHdrHex(ZNAK, ZmZeros, info) ;	  }	  return 0 ;	}	switch( info->DataType ) {	  /* hex header is 14 hex digits, cr, lf.  Optional xon is ignored */#define isxdigit(c) ((c >= '0'&&c <= '9')||(c >= 'a'&&c <= 'z')||(c >= 'A'&& c<= 'Z'))	  case ZHEX:	    if( info->chrCount <= 14  &&   !isxdigit(c) ) {		info->InputState = Idle;		info->chrCount = 0 ;		return ZXmitHdrHex(ZNAK, ZmZeros, info) ;	    }	    if( info->chrCount <= 14 ) {	      i = (info->chrCount-1)/2 ;	      info->hdrData[i] = ZmRcvHex(info->hdrData[i], c) ;	    }	    if( info->chrCount == 16 ) {	      crc = 0 ;	      for(i=0; i<7; ++i)		crc = updcrc(info->hdrData[i], crc) ;	      info->InputState = Idle;	      info->chrCount = 0 ;	      if( (crc&0xffff) != 0 )		return ZXmitHdrHex(ZNAK, ZmZeros, info) ;	      else		return ZmProtocol(info) ;	    }	    else	      ++info->chrCount ;	    break ;	  case ZBIN:	    /* binary header is type, 4 bytes data, 2 bytes CRC */	    info->hdrData[info->chrCount-1] = c ;	    info->crc = updcrc(c, info->crc) ;	    if( ++info->chrCount > 7 ) {	      info->InputState = Idle;	      info->chrCount = 0 ;	      if( (crc&0xffff) != 0 )		return ZXmitHdrHex(ZNAK, ZmZeros, info) ;	      else		return ZmProtocol(info) ;	    }	    break ;	  case ZBIN32:	    /* binary32 header is type, 4 bytes data, 4 bytes CRC */	    info->hdrData[info->chrCount-1] = c ;	    info->crc = UPDC32(c, info->crc) ;	    if( ++info->chrCount > 9 ) {	      info->InputState = Idle;	      info->chrCount = 0 ;	      if( info->crc != 0xdebb20e3 )	/* see note below */		return ZXmitHdrHex(ZNAK, ZmZeros, info) ;	      else		return ZmProtocol(info) ;	    }	    break ;	}	return 0 ;}	/* handle character input in a data buffer */static	int ZmDataChar( u_char c, ZModem *info ){	if( c == ZDLE ) {	  info->escape = 1 ;	  return 0 ;	}	if( info->escape ) {	  info->escape = 0 ;	  switch( c ) {	    case ZCRCE:	    case ZCRCG:	    case ZCRCQ:	    case ZCRCW:	      info->PacketType = c ;	      info->crcCount = (info->DataType == ZBIN32) ? 4 : 2 ;		if( info->DataType == ZBIN )		  info->crc = updcrc(c, info->crc) ;		else		  info->crc = UPDC32(c, info->crc) ;	      return 0 ;	    case ZRUB0: c = 0177 ; break ;	    case ZRUB1: c = 0377 ; break ;	    default: c ^= 0100 ; break ;	  }	}	switch( info->DataType ) {	  /* TODO: are hex data packets ever used? */	  case ZBIN:	    info->crc = updcrc(c, info->crc) ;	    if( info->crcCount == 0 )	      info->buffer[info->chrCount++] = c ;	    else if( --info->crcCount == 0 ) {	      return ZmDataReceived(info, (info->crc&0xffff) == 0) ;	    }	    break ;	  case ZBIN32:	    info->crc = UPDC32(c, info->crc) ;	    if( info->crcCount == 0 )	      info->buffer[info->chrCount++] = c ;	    else if( --info->crcCount == 0 ) {	      return ZmDataReceived(info, info->crc == 0xdebb20e3) ;	    }	    break ;	}	return 0 ;}	/* wait for "OO" */static	int ZmFinishChar( char c, ZModem *info ){	if( c == 'O' ) {	  if( ++info->chrCount >= 2 )	    return ZmDone ;	}	else	  info->chrCount = 0 ;	return 0 ;}/* PROTOCOL LOGIC:  This section of code handles the actual * protocol.  This is also driven by a finite state machine * * State tables are sorted by approximate frequency order to * reduce search time. */	/* Extra ZRINIT headers are the receiver trying to resync.  */	/* If compiling for Send Only or Receive Only, convert table	 * entries to no-ops so we don't have to link zmodem[rt].o	 */#if	SendOnly#define	RStartOps	DoneOps#define	RSinitWaitOps	DoneOps#define	RFileNameOps	DoneOps#define	RCrcOps		DoneOps#define	RFileOps	DoneOps#define	RDataOps	DoneOps#define	RFinishOps	DoneOps#define	ZmGotFileName	ZmIgnore#define	ZmResendCrcReq	ZmIgnore#define	ZmGotSinitData	ZmIgnore#define	ZmResendRpos	ZmIgnore#define	ZmGotFileData	ZmIgnore#define	ZmSendRinit	ZmIgnore#elseextern	StateTable	RStartOps[] ;extern	StateTable	RSinitWaitOps[] ;extern	StateTable	RFileNameOps[] ;extern	StateTable	RCrcOps[] ;

⌨️ 快捷键说明

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