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

📄 ian_xmodem.c

📁 MIPS架构Xmodem和Ymodem源码程序
💻 C
📖 第 1 页 / 共 3 页
字号:
					printf("%s\n", xerr_msg(XERR_NOFILE));					return(CMD_FAILURE);				}				memcpy((char *)(xif.dataddr), TFS_BASE(tfp), tfp->filsize);#endif			}			r = Xdown(&xif, XMODEM);			if (size) {				/* override size by user specified value */				xif.size = size;			}			printf("\n");			if ( r < 0 ) {				printf("%s\n", xerr_msg(r));				return(CMD_FAILURE);			}			if ( ! xif.verify ) {#if INCLUDE_TFS				if (xif.size > 0 && fname && fname[0]) {					/* save file to TFS */					r = tfsadd(fname, info, flags, 							   (uchar *)xif.dataddr, xif.size);					if (r != TFS_OKAY) {						printf("%s: %s: %s\n",							   xerr_msg(XERR_TFS),							   fname, (char *)tfsctrl(TFS_ERRMSG,r,0));						return(CMD_FAILURE);					}				}#endif			}						printf("Rcvd 1 file.\n");			if ( xif.verify ) {				printf(" %s: %ld bytes, %d blocks, %d errors, "					   "first err @ 0x%08lx\n",					   fname[0] ? fname : "<noname>",					   xif.size,					   xif.pktcnt,					   xif.errcnt, xif.firsterrat);			} else {				printf(" %s: %ld bytes, %d blocks, @ 0x%08lx\n",					   fname[0] ? fname : "<no-name>",					   xif.size,					   xif.pktcnt,					   xif.dataddr);			}		}#if INCLUDE_FLASH		/* whether it is an X or a Y modem download, if newboot		   is set, the (last) downloaded file will be written		   to the boot-sector */		if (xif.size > 0 && newboot) {			extern	int FlashProtectWindow;			char	*bb;			ulong	bootbase;						bb = getenv("BOOTROMBASE");			if (bb)				bootbase = strtoul(bb,0,0);			else				bootbase = BOOTROM_BASE;						FlashProtectWindow = 1;			printf("Reprogramming boot @ 0x%lx from 0x%lx, %ld bytes.\n",				   bootbase, xif.dataddr, xif.size);			if (askuser("OK?")) {				if (flashewrite(&FlashBank[0], (char *)bootbase,					 (char *)xif.dataddr, xif.size) == -1) {					/* flashewrite should never return */					printf("failed\n");					return(CMD_FAILURE);				}			}		}#endif	} else {		/* Neither Upload nor Download */		return(CMD_PARAM_ERROR);	}	return(CMD_SUCCESS);}/***************************************************************************/static char*xerr_msg (int code){	return (code >= 0) ? xerr_msgs[0] : xerr_msgs[-code];}/***************************************************************************/static voiddoCAN (void) {	waitclear();	/* send eight CANs */	rputchar(CAN); rputchar(CAN);	rputchar(CAN); rputchar(CAN);	rputchar(CAN); rputchar(CAN);	rputchar(CAN); rputchar(CAN);	/* send eight backspaces */	rputchar(BS); rputchar(BS);	rputchar(BS); rputchar(BS);	rputchar(BS); rputchar(BS);	rputchar(BS); rputchar(BS);	waitclear();}/*************************************************************************** * DOWNLOAD STUFF **************************************************************************//* getPacket(): * Used by Xdown to retrieve packets. */static intgetPacket(uchar *pkt, int len, int usecrc){	int	i;	uchar seq[2];	/* s: Get and check the frame sequence number */	if ( waitbytes(seq, 2, CHAR_TMO) < 0 ) {		Mtrace("T<seq>");		return -1;	}	if ( seq[0] != (uchar)(~seq[1]) ) {		Mtrace("~<%02x != %02x>", seq[0], seq[1]);		return -1;	}	Mtrace("s");	/* d: Get the frame's data */					if ( waitbytes(pkt, len, CHAR_TMO) < 0 ) {		Mtrace("T<data>");		return -1;	}	Mtrace("d");	/* d: Get the frame's CRC or checksum */	if ( usecrc ) {		int c;		ushort	crc, xcrc;				c = waitchar(CHAR_TMO);		if ( c < 0 ) {			Mtrace("T<crc>");			return -1;		}		crc = (ushort)c << 8;		c = (uchar)waitchar(CHAR_TMO);		if ( c < 0 ) {			Mtrace("T<crc>");			return -1;		}		crc |= (ushort)c;		xcrc = xcrc16((uchar *)pkt,(ulong)(len));		if (crc != xcrc) {			Mtrace("C<%04x != %04x>", crc, xcrc);			return -1;		}	} else {		uchar csum; 		int xcsum;		xcsum = waitchar(CHAR_TMO);		if ( xcsum < 0 ) {			Mtrace("T<xcsum>");			return -1;		}		csum = 0;		for(i=0; i < len; i++)			csum += *pkt++;		if (csum != xcsum) {			Mtrace("c<%02x != %02x>",csum,xcsum);			return -1;		}	}	Mtrace("c");	return seq[0];}/***************************************************************************//* * waitPacket * * Receive a X or Y modem packet. Step the reception state-machine. * * Acknowledge the previous frame (or 'kick' the transmiter with a 'C'  * or NAK if this is the first frame), and receive the next-one. Also  * handle frame retransmitions. * * Arguments: *   - pb - packet (frame) buffer. Write the packet-data here. *   - *len - packet's size in bytes will be written here *   - sno - packet sequence number to wait for. *   - usercrc - if non-zero, user 16-bit CRC instread of 8-bit checksum. * * Returns: *   0 - if packet was received successfully *   1 - if an EOT was received instead of a packet *   Something negative on fatal error: *     XERR_SYNC : Synchronization lost *     XERR_CAN : Operation canceled *     XERR_UCAN : Operation canceled by user */static intwaitPacket (uchar *pb, int *len, ulong lsno, int usecrc){	char nak;	int done, rval;	int c, r, sno, psize;		if ( usecrc ) {		nak = 'C';	} else {		nak = NAK;	}	if ( (lsno == 0 || lsno == 1) ) {		/* if it is the first frame of a X or Y modem session,		   'kick' the transmiter by sending a NAK or a 'C' */		rputchar(nak);	} else {		/* if it is not the first frame of an X or Y modem session,		   acknowledge the previous frame */		rputchar(ACK);	}	sno = lsno % 0x100;	/* loop exitst with:	   done = 1: packet received succesfully	   done = 2: EOT received and acknowledged	   done < 0: Fatal error. 'done' holds error code. */	do {		done = 0;		c = waitchar(FRAME_TMO);		switch ( c ) {		case STX:		case SOH:			/* ok, its a block */			Mtrace("P[");			*len = psize = (c == STX) ? 1024 : 128;			r = getPacket(pb, psize, usecrc);			Mtrace("]");			if (r < 0) {				/* block reception not ok. request retransmission */				waitclear();				rputchar(nak);				break;			}			if ( r != sno ) {				/* block sequence number is not quite right, 				   but it might still do */				if ( (lsno == 0) || ( sno - r != 1 && r - sno != 0xff ) ) {					/* shit! desperately out of sync. 					   CAN the whole thing */					Mtrace("S<%02x != %02x>", r, sno);					doCAN();					done = XERR_SYNC;				} else {					/* no worries, it's just a retransmission */					Mtrace("S");					rputchar(ACK);					if (lsno == 1) {						Mtrace("0");						rputchar(nak);					}				}			} else {				/* seq. number just fine */				Mtrace("s");				if ( lsno == 0 ) {					Mtrace("0");					rputchar(ACK);				}				done = 1;			}			break;		case CAN:			Mtrace("C");			/* wait for a second CAN */			c = (char)waitchar(CHAR_TMO);			if (c != CAN) {				Mtrace("<%02x>", c);				waitclear();				rputchar(nak);			} else {				Mtrace("C");				done = XERR_CAN;			}			break;		case ESC:			/* User-invoked abort */			Mtrace("X");			/* wait for a second ESC */			c = (char)waitchar(CHAR_TMO);			if (c != ESC) {				waitclear();				rputchar(nak);				done = 0;			} else {				done = XERR_UCAN;			}			break;		case EOT:			Mtrace("E");			/* first make sure that this is really an EOT,			   and not a corrupted start-frame; use the fact that			   self-respecting EOTs always come alone, not followed                by other characters. */ 			c = waitchar(CHAR_TMO);			if ( c >= 0 ) {				/* probably not an EOT, request retransmission */				Mtrace("<%02x>", c);				waitclear();				rputchar(nak);				break;			}			/* ok it is probably a true EOT, send an ACK */			rputchar(ACK);			Mtrace("a", c);			if (lsno != 0) {				done = 2;			}			break;		default:			/* request retransmission */			Mtrace("?<%02x>",(uchar)c);			waitclear();			rputchar(nak);			break;		}	} while (!done);	if (done == 1) {		rval = 0;	} else if (done == 2) {		rval = 1;	} else {		rval = done;	}	return rval;}/***************************************************************************//* Xdown(): * * Download, or verify a file using the XMODEM protocol * * Arguments: *   - xip - structure containing transfer info: *	  usecrc       IN  - use 16bit-CRC instead of 8bit-checksum. *    verify       IN  - operate in verification mode. *	  dataddr:     IN  - downloaded file will be stored starting from here. *                       in verification mode, downloaded file will be  *                       compared with data starting from here. *	  size:        OUT - size of received file in bytes.  *	  pktcnt:      OUT - number of frames transfered. *	  errcnt:      OUT - number of errors, if mode is verification. *	  firsterrat:  OUT - address of first error, if mode is verification. *  - proto - protocol type (y-modem or x-modem); Used to make very small  *  adjustment to the operation of the function.  * * Returns: *    On success: something non-negative. *    On error: something negative. *      XERR_GEN : General error *      XERR_TOUT : Timeout *      XERR_SYNC : Lost synchronization *      XERR_CAN : Operation canceled *      XERR_UCAN : Operation canceled by user */static intXdown(struct xinfo *xip, int proto){	int i, r;	ulong sno;	int psize;	char *tmppkt, *dataddr;	Mtrace("--XD--");	dataddr = (char *)(xip->dataddr);	if ( xip->verify ) {		tmppkt = pktbuff;	} else {		tmppkt = (char *)(xip->dataddr);	}	sno = 1;	xip->pktcnt = 0;	xip->errcnt = 0;	xip->firsterrat = 0;	xip->size = 0;	do {		r = waitPacket(tmppkt, &psize, sno, xip->usecrc);		if ( r == 0 ) {			sno++;			xip->pktcnt++;			xip->size += psize;			if ( xip->verify ) {				for (i = 0; i < psize; i++, dataddr++) {					if (tmppkt[i] != *dataddr) {						if (xip->errcnt++ == 0)							xip->firsterrat = (ulong)dataddr;					}				}			} else {				tmppkt += psize;			}		}	} while ( ! r );	if ( r == 1 && proto == XMODEM ) {		/* send a couple more ACKs to make sure that at least 		   one reaches its destination */		rputchar(ACK); rputchar(ACK); rputchar(ACK);		rputchar(ACK); rputchar(ACK); rputchar(ACK);		/* send backspaces in-case ACKs have reached the user's		   terminal */		rputchar(BS); rputchar(BS); rputchar(BS);		rputchar(BS); rputchar(BS); rputchar(BS);	}	if (proto == XMODEM) {		/* trash any final garbage send by the transmiter */		waitclear();	}	return r;}/***************************************************************************//* Ydown(): * * Download (uMon <-- Host) a file using the YMODEM protocol * * Arguments: *   - yip - structure containing transfer info: *    usecrc       IN  - use 16bit CRC instead of 8bit checksum. *	  onek         x *    verify       IN  - verify the downloaded file against stored data.     *	  baseaddr:    IN  - download the first file here. *    flags        IN  - TFS flags to use when writing to TFS.  *    info         IN  - TFS info to use when writing to TFS. *    filecnt      OUT - Number of files successfully downloaded. *    fname[i]     OUT - Name of the i'th file downloaded. *	  size[i]:     OUT - size of the i'th file downloaded in bytes. *	  pktcnt[i]:   OUT - nr of frames transfered when downloading i'th file. *	  errcnt[i]:   OUT - number of errors detected when verifying i'th file. *	  firsterrat[i]: OUT - address of the first error of the i'th file. * * Returns: *    On success: something non-negative. *    On error: something negative. *      XERR_GEN : General error *      XERR_TOUT : Timeout *      XERR_NOFILE : File not found (verification mode) *      XERR_TFS : TFS error *      XERR_SYNC : Synchronization error *      XERR_CAN : Operation canceled *      XERR_UCAN : Operation canceled by user */static intYdown(struct yinfo *yip){	TFILE *tfp;	int rval, r, psize;	char *tmppkt;	ulong dataddr;	char *fname, *basename, *s1, *fsize;	rval = 0;	yip->filecnt = 0;	tmppkt = pktbuff;	dataddr = yip->baseaddr;	do {		yip->dataddr[yip->filecnt] = dataddr;		yip->size[yip->filecnt] = 0;		yip->pktcnt[yip->filecnt] = 0;		yip->errcnt[yip->filecnt] = 0;		yip->firsterrat[yip->filecnt] = 0;		/* 		 * receive and parse the header-block 		 */		r = waitPacket(tmppkt, &psize, 0, 1);		if ( r < 0 ) {			rval = r;			break;		}		/* first comes the file-name */		fname = (char *)(tmppkt);		/* buggy ymodems delimit fields with SP instead of NULL.		   Cope. */		s1 = strchr(fname,' ');		if (s1) *s1 = '\0';		/* if file-name contains path, cut it off and just keep		   the stem */		basename = strrchr(fname,'/');		if (! basename) basename = fname;		/* after the file-name comes the file-size */		fsize = basename + strlen(basename) + 1;		/* buggy ymodems delimit fields with SP instead of NULL.		   cope. */		s1 = strchr(fsize,' ');		if (s1) *s1 = '\0';				/* copy info to xip fields */		yip->size[yip->filecnt] = atoi(fsize);		strcpy(yip->fname[yip->filecnt], basename);		Mtrace("<f=%s>",yip->fname[yip->filecnt]);		Mtrace("<z=%d>",yip->size[yip->filecnt]);		Mtrace("]");		if ( ! yip->fname[yip->filecnt][0] )

⌨️ 快捷键说明

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