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

📄 zmodemt.c

📁 本source code 為s3c4510的bootloader
💻 C
📖 第 1 页 / 共 3 页
字号:
	  {ZFERR,ZmGotAbort,1,1,TFinish},	  {ZCOMMAND,ZmGotCommand,0,0,CommandData},	  {ZSTDERR,ZmGotStderr,0,0,StderrData},	  {99,ZmZPF,0,0,TInit},	} ;		/* sent ZFILE, waiting for response */	StateTable	FileWaitOps[] = {	  {ZRPOS,ZmSendFileData,1,0,Sending},	  {ZSKIP,ZmSkipFile,1,0,FileWait},	  {ZCRC,ZmSendFileCrc,1,0,FileWait},	  {ZNAK,ZmSendFilename,1,0,FileWait},	  {ZRINIT,ZmSendFilename,1,1,FileWait},	/* rcvr confused, retry file */	  {ZABORT,ZmGotAbort,1,1,TFinish},	  {ZFERR,ZmGotAbort,1,1,TFinish},	  {ZCHALLENGE,ZmAnswerChallenge,1,0,FileWait},	  {ZCOMMAND,ZmGotCommand,0,0,CommandData},	  {ZSTDERR,ZmGotStderr,0,0,StderrData},	  {99,ZmZPF,0,0,FileWait},	} ;		/* sent file CRC, waiting for response */	StateTable	CrcWaitOps[] = {	  {ZRPOS,ZmSendFileData,1,0,Sending},	  {ZSKIP,ZmSkipFile,1,0,FileWait},	  {ZNAK,ZmSendFileCrc,1,0,CrcWait},	  {ZRINIT,ZmSendFilename,1,1,FileWait},	/* rcvr confused, retry file */	  {ZABORT,ZmGotAbort,1,1,TFinish},	  {ZFERR,ZmGotAbort,1,1,TFinish},	  {ZCRC,ZmSendFileCrc,0,0,CrcWait},	  {ZCHALLENGE,ZmAnswerChallenge,0,0,CrcWait},	  {ZCOMMAND,ZmGotCommand,0,0,CommandData},	  {ZSTDERR,ZmGotStderr,0,0,StderrData},	  {99,ZmZPF,0,0,CrcWait},	} ;		/* sending data, interruptable */	StateTable	SendingOps[] = {	  {ZACK,ZmGotSendAck,0,0,Sending},	  {ZRPOS,ZmGotSendPos,1,1,Sending},	  {ZSKIP,ZmSkipFile,1,1,FileWait},	  {ZNAK,ZmGotSendNak,1,1,Sending},	  {ZRINIT,ZmSendFilename,1,1,FileWait},	/* rcvr confused, retry file */	  {ZABORT,ZmGotAbort,1,1,TFinish},	  {ZFERR,ZmGotAbort,1,1,TFinish},	  {99,ZmZPF,0,0,SendWait},	} ;		/* sent data, need to send EOF */	StateTable	SendDoneOps[] = {	  {ZACK,ZmGotSendDoneAck,0,0,SendWait},	  {ZRPOS,ZmGotSendPos,1,1,Sending},	  {ZSKIP,ZmSkipFile,1,1,FileWait},	  {ZNAK,ZmGotSendNak,1,1,Sending},	  {ZRINIT,ZmSendFilename,1,1,FileWait},	/* rcvr confused, retry file */	  {ZABORT,ZmGotAbort,1,1,TFinish},	  {ZFERR,ZmGotAbort,1,1,TFinish},	  {99,ZmZPF,0,0,SendWait},	} ;		/* sending data, waiting for ACK */	StateTable	SendWaitOps[] = {	  {ZACK,ZmGotSendWaitAck,0,0,Sending},	  {ZRPOS,ZmGotSendPos,0,0,SendWait},	  {ZSKIP,ZmSkipFile,1,1,FileWait},	  {ZNAK,ZmGotSendNak,0,0,Sending},	  {ZRINIT,ZmSendFilename,1,1,FileWait},	/* rcvr confused, retry file */	  {ZABORT,ZmGotAbort,1,1,TFinish},	  {ZFERR,ZmGotAbort,1,1,TFinish},	  {99,ZmZPF,0,0,SendWait},	} ;		/* sent ZEOF, waiting for new RINIT */	StateTable	SendEofOps[] = {	  {ZRINIT,ZmSkipFile,1,0,TStart},	/* successful completion */	  {ZACK,ZmIgnore,0,0,SendEof},	/* probably ACK from last packet */	  {ZRPOS,ZmGotSendPos,1,1,SendWait},	  {ZSKIP,ZmSkipFile,1,1,TStart},	  {ZNAK,ZmResendEof,1,0,SendEof},	  {ZRINIT,ZmSendFilename,1,1,FileWait},	/* rcvr confused, retry file */	  {ZABORT,ZmGotAbort,1,1,TFinish},	  {ZFERR,ZmGotAbort,1,1,TFinish},	  {99,ZmZPF,0,0,SendEof},	} ;	StateTable	TFinishOps[] = {	  {ZFIN,ZmOverAndOut,1,1,Done},	  {ZNAK,ZmTFinish,1,1,TFinish},	  {ZRINIT,ZmTFinish,1,1,TFinish},	  {ZABORT,ZmGotAbort,1,1,TFinish},	  {ZFERR,ZmGotAbort,1,1,TFinish},	  {99,ZmZPF,0,0,TFinish},	} ;extern	char	*hdrnames[] ;	/* Received Rinit.  Usually received while in start state,	 * this can also be an attempt to resync after a protocol	 * failure	 */static	int ZmGotRinit( ZModem *info ){	info->bufsize = info->hdrData[1] + info->hdrData[2]*256 ;	info->zrinitflags = info->hdrData[4] + info->hdrData[3]*256 ;	info->crc32 = info->zrinitflags & CANFC32 ;	info->escCtrl = info->zrinitflags & ESCCTL ;	info->escHibit = info->zrinitflags & ESC8 ;	/* Full streaming: If receiver can overlap I/O, and if	 * the sender can sample the reverse channel without hanging,	 * and the receiver has not specified a buffer size, then we	 * can simply blast away with ZCRCG packets.  If the receiver	 * detects an error, it sends an attn sequence and a new ZRPOS	 * header to restart the file where the error occurred.	 *	 * [note that zmodem8.doc does not define how much noise is	 * required to trigger a ZCRCW packet.  We arbitrarily choose	 * 64 bytes]	 *	 * If 'windowsize' is nonzero, and the receiver can do full	 * duplex, ZCRCQ packets are sent instead of ZCRCG, to keep track	 * of the number of characters in the queue.  If the queue fills	 * up, we pause and wait for a ZACK.	 *	 *	 * Full Streaming with Reverse Interrupt:  If sender cannot	 * sample the input stream, then we define an Attn sequence	 * that will be used to interrupt transmission.	 *	 *	 * Full Streaming with Sliding Window:  If sender cannot	 * sample input stream or respond to Attn signal, we send	 * several ZCRCQ packets until we're sure the receiver must	 * have sent back at least one ZACK.  Then we stop sending and	 * read that ZACK.  Then we send one more packet and so on.	 *	 *	 * Segmented Streaming:  If receiver cannot overlap I/O or can't do	 * full duplex and has specified a maximum receive buffer size,	 * whenever the buffer size is reached, we send a ZCRCW packet.	 *	 * TODO: what if receiver can't overlap, but hasn't set a buffer	 * size?	 *	 * ZCRCE: CRC next, frame ends, header follows	 * ZCRCG: CRC next, frame continues nonstop	 * ZCRCQ: CRC next, send ZACK, frame continues nonstop	 * ZCRCW: CRC next, send ZACK, frame ends, header follows	 */	ZFlowControl(1,info) ;	if( (info->zrinitflags & (CANFDX|CANOVIO)) == (CANFDX|CANOVIO) &&	    (SendSample||SendAttn)  &&	    info->bufsize == 0 )	{	  if( info->windowsize == 0 )           {	    info->Streaming = Full;           }	  else           {	    info->Streaming = StrWindow;           }	}	else if( (info->zrinitflags & (CANFDX|CANOVIO)) == (CANFDX|CANOVIO) &&	    info->bufsize == 0 )	{	  info->Streaming = SlidingWindow;	}	else	  info->Streaming = Segmented;#ifdef ZMODEMLOG	zmodemlog("GotRinit[%s]\n", ZmSname(info)) ;#endif 								// ZMODEMLOG	if( AlwaysSinit || info->zsinitflags != 0  ||  info->attn != NULL )	  return(ZmSendZSInit(info));	else	  return ZmDone ;	/* caller now calls ZmTFile() */}static	int ZmSendZSInit( ZModem *info ){ int	err ; const char	*at = (info->attn != NULL) ? info->attn : "" ; u_char	fbuf[4] ; int pos; pos = 0; while( *(at + pos) != '\0' ) { pos += 1; } 	/* TODO: zmodem8.doc states: "If the ZSINIT header specifies	 * ESCCTL or ESC8, a HEX header is used, and the receiver	 * activates the specified ESC modes before reading the following	 * data subpacket." What does that mean?	 */#ifdef ZMODEMLOG	zmodemlog("SendZSInit[%s]\n", ZmSname(info)) ;#endif 								// ZMODEMLOG	info->state = TInit ;	fbuf[0] = fbuf[1] = fbuf[2] = 0 ;	fbuf[3] = info->zsinitflags ;        err = ZXmitHdr(ZSINIT, ZBIN, fbuf, info);	if(err) { return(err); }	err = ZXmitData(ZBIN, pos+1, ZCRCW, (u_char *)at, info);	if(err) { return(err); } 	return(0);}static	int ZmSendFileCrc( ZModem *info ){	u_long	crc ;	crc = FileCrc(info->filename) ;#ifdef ZMODEMLOG	zmodemlog("SendFileCrc[%s]: %lx\n", ZmSname(info), crc) ;#endif								//ZMODEMLOG		return ZXmitHdrHex(ZCRC, ZEnc4(crc), info) ;}/* Utility: start sending data. */static	int ZmStartFileData(  ZModem *info ){	int	err ;	info->offset =	info->lastOffset =	info->zrposOffset = ZDec4(info->hdrData+1) ;        ZFileSeek(info->file, info->offset, info);	/* TODO: what if fseek fails?  Send EOF? */#ifdef ZMODEMLOG	zmodemlog("startFileData[%s]: %ld\n", ZmSname(info), info->offset) ;#endif 								// ZMODEMLOG        err = ZXmitHdr(ZDATA, ZBIN, info->hdrData+1, info);	if(err) { return(err); }	return (ZmSendMoreFileData(info));}	/* send a chunk of file data in response to a ZRPOS.  Whether this	 * is followed by a ZCRCE, ZCRCG, ZCRCQ or ZCRCW depends on all	 * sorts of protocol flags	 */static	int ZmSendFileData( ZModem *info ){	info->waitflag = 0 ;	return(ZmStartFileData(info));}/* here if an ACK arrived while transmitting data.  Update * last known receiver offset, and try to send some more * data. */static	int ZmGotSendAck( ZModem *info ){	u_long offset ;	offset = ZDec4(info->hdrData+1) ;	if( offset > info->lastOffset )	  info->lastOffset = offset ;#ifdef ZMODEMLOG	zmodemlog("GotSendAck[%s]: %ld\n", ZmSname(info), info->offset) ;#endif 								// ZMODEMLOG	return 0 ;		/* DONT send more data, that will happen				 * later anyway */}/* here if an ACK arrived after last file packet sent.  Send * the EOF. */static	int ZmGotSendDoneAck( ZModem *info ){	u_long offset ;	offset = ZDec4(info->hdrData+1) ;	if( offset > info->lastOffset )	  info->lastOffset = offset ;#ifdef ZMODEMLOG	zmodemlog("GotSendDoneAck[%s]: %ld\n", ZmSname(info), info->offset) ;#endif							// 	info->state = SendEof ;	info->timeout = 60 ;	return ZXmitHdrHex(ZEOF, ZEnc4(info->offset), info) ;}	/* off to a bad start; ZDATA header was corrupt.  Start	 * from beginning	 */static	int ZmGotSendNak( ZModem *info ){	info->offset = info->zrposOffset ;        ZFileSeek(info->file, info->offset, info);	/* TODO: what if fseek fails?  Send EOF? */#ifdef ZMODEMLOG	zmodemlog("GotSendNak[%s]: %ld\n", ZmSname(info), info->offset) ;#endif	return (ZmSendMoreFileData(info));}	/* got a ZSKIP, receiver doesn't want this file.  */static	int ZmSkipFile( ZModem *info ){#ifdef ZMODEMLOG zmodemlog("SkipFile[%s]\n", ZmSname(info)) ;#endif 								// ZMODEMLOG ZCloseFile(info->file, info); return ZmDone ;}	/* got a ZRPOS packet in the middle of sending a file,	 * set new offset and try again	 */static	int ZmGotSendPos( ZModem *info ){	ZStatus(DataErr, ++info->errCount, NULL) ;	info->waitflag = 1 ;		/* next pkt should wait, to resync */#ifdef ZMODEMLOG	zmodemlog("GotSendPos[%s]\n", ZmSname(info), info->offset) ;#endif 							// ZMODEMLOG	return(ZmStartFileData(info));}	/* here if an ACK arrived while waiting while transmitting data.	 * Update last known receiver offset, and try to send some more	 * data.	 */static	int ZmGotSendWaitAck( ZModem *info ){	u_long	offset ;	int	err ;	offset = ZDec4(info->hdrData+1) ;	if( offset > info->lastOffset )	  info->lastOffset = offset ;#ifdef ZMODEMLOG	zmodemlog("GotSendWaitAck[%s]\n", ZmSname(info), offset) ;#endif 								// ZMODEMLOG	err = ZXmitHdr(ZDATA, ZBIN, ZEnc4(info->offset), info);	if(err) return(err);	return (ZmSendMoreFileData(info));}static	int ZmResendEof( ZModem *info ){	return ZXmitHdrHex(ZEOF, ZEnc4(info->offset), info) ;}static	int ZmOverAndOut( ZModem *info ){	ZXmitStr((u_char *)"OO", 2, info) ;	return ZmDone ;}	/* YMODEM */static	u_char	eotstr[1] = {EOT} ;	/* ymodem parser */int YsendChar( char c, ZModem *info ){	int	err ;	if( info->canCount >= 2 ) {	  ZStatus(RmtCancel, 0, NULL) ;	  return ZmErrCancel ;	}	switch( info->state ) {	  case YTStart:		/* wait for 'G', 'C' or NAK */	    switch( c ) {	      case 'G':		/* streaming YModem */	      case 'C':		/* CRC YModem */	      case NAK:		/* checksum YModem */		info->PacketType = c ;		return ZmDone ;	      default:		return 0 ;	    }	  case YTFile:		/* sent filename, waiting for ACK or NAK */	    switch( c ) {	      case NAK:		/* resend */	      case 'C':	      case 'G':		ZStatus(DataErr, ++info->errCount, NULL) ;		return YSendFilename(info) ;	      case ACK:		info->state = YTDataWait ;	      default:		return 0 ;	    }	  case YTDataWait:	/* sent filename, waiting for G,C or NAK */	    switch( c ) {	      case NAK:	      case 'C':	      case 'G':		info->chrCount = 0 ;		if( info->PacketType == 'G' )	/* send it all at once */		{		  while( info->state == YTData )		   {		    err = YSendData(info);			    if(err)                     {		      return(err);                     }                   } 		  return 0 ;		}		else		  return YSendData(info) ;	      default:		return 0 ;	    }	  case YTData:		/* sent data, waiting for ACK or NAK */

⌨️ 快捷键说明

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