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

📄 xmodem.c

📁 MIPS架构Xmodem和Ymodem源码程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	 * character in the response.	 */	if (xip->pktcnt == -1)		c = getchar();	return(c);}/* getPacket(): * Used by Xdown to retrieve packets. */static int getPacket(uchar *tmppkt, struct xinfo *xip){	int		i;	char	*pkt;	uchar	seq[2];	if (getbytes(seq,2,1) != 2)		return(-1);	if (xip->flags & VERIFY) {		if (getbytes(tmppkt,xip->pktlen,1) != xip->pktlen)			return(-1);		for(i=0;i<xip->pktlen;i++) {			if (tmppkt[i] != ((char *)xip->dataddr)[i]) {				if (xip->errcnt++ == 0)					xip->firsterrat = (char *)(xip->dataddr+i);			}		}		pkt = (char *)tmppkt;	}	else {		if (getbytes((char *)xip->dataddr,xip->pktlen,1) != xip->pktlen)			return(-1);		pkt = (char *)xip->dataddr;	}	if (xip->flags & USECRC) {		ushort	crc, xcrc;		    	/* An "endian independent way to combine the CRC bytes. */    	crc  = (ushort)getchar() << 8;	    crc += (ushort)getchar();		xcrc = xcrc16((uchar *)pkt,(ulong)(xip->pktlen));		if (crc != xcrc) {			rputchar(NAK);			//Mtrace("CRC %04x != %04x",crc,xcrc);			return(0);		}	}	else {		uchar	csum, xcsum;		xcsum = (uchar)getchar();		csum = 0;		for(i=0;i<xip->pktlen;i++)			csum += *pkt++;		if (csum != xcsum) {			rputchar(NAK);			//Mtrace("CSUM %02x != %02x (%d)",csum,xcsum,xip->pktlen);			return(0);		}		//Mtrace("CSUM %02x (%d)",csum,xip->pktlen);	}	/* Test the sequence number compliment...	 */	if ((uchar)seq[0] != (uchar)~seq[1]) {		rputchar(NAK);		//Mtrace("SNOCMP %02x != %02x",(uchar)seq[0],(uchar)~(seq[1]));		return(0);	}	/* Verify that the incoming sequence number is the expected value...	 */	if ((uchar)seq[0] !=  xip->sno) {		/* If the incoming sequence number is one less than the expected		 * sequence number, then we assume that the sender did not recieve		 * our previous ACK, and they are resending the previously received		 * packet.  In that case, we send  ACK and don't process the		 * incoming packet...	 	 */		if ((uchar)seq[0] == xip->sno-1) {			//Mtrace("R_ACK");			rputchar(ACK);			return(0);		}		/* Otherwise, something's messed up...		 */		rputchar(CAN);		//Mtrace("SNO: %02x != %02x",seq[0],xip->sno);		return(-1);	}	/* First packet of YMODEM contains information about the transfer:	 * FILENAME SP FILESIZE SP MOD_DATE SP FILEMODE SP FILE_SNO	 * Only the FILENAME is required and if others are present, then none	 * can be skipped.	 */	if ((xip->flags & YMODEM) && (xip->pktcnt == 0)) {		char *slash, *space, *fname;		slash = strrchr((char *)(xip->dataddr),'/');		space = strchr((char *)(xip->dataddr),' ');		if (slash)			fname = slash+1;		else			fname = (char *)(xip->dataddr);		//Mtrace("<fname=%s>",fname);		if (space) {			*space = 0;			xip->size = atoi(space+1);		}		strcpy(xip->fname,fname);		if (fname[0])			xip->filcnt++;	}	else		xip->dataddr += xip->pktlen;	xip->sno++;	xip->pktcnt++;	xip->xfertot += xip->pktlen;	//Mtrace("ACK");	rputchar(ACK);	if (xip->flags & YMODEM) {		if (xip->fname[0] == 0) {			printf("\nRcvd %d file%c\n",				xip->filcnt,xip->filcnt > 1 ? 's' : ' ');			return(1);		}	}	return(0);}/* Xup(): * Called when a transfer from target to host is being made (considered * an upload). */static int Xup(struct xinfo *xip){	unsigned char	c, buf[PKTLEN_128];	int		done, pktlen;	long	actualsize;	//Mtrace("Xup starting");	actualsize = xip->size;	if (xip->size & 0x7f) {		xip->size += 128;		xip->size &= 0xffffff80L;	}	printf("Upload %ld bytes from 0x%lx\n",xip->size,(ulong)xip->base);	/* Startup synchronization... */	/* Wait to receive a NAK or 'C' from receiver. */	done = 0;	while(!done) {		c = (uchar)getchar();		switch(c) {		case NAK:			done = 1;			//Mtrace("CSM");			break;		case 'C':			xip->flags |= USECRC;			done = 1;			//Mtrace("CRC");			break;		case 'q':	/* ELS addition, not part of XMODEM spec. */			return(0);		default:			break;		}	}        /*  look for ymodem	if (xip->flags & YMODEM) {		//Mtrace("SNO_0");		xip->sno = 0;		xip->pktcnt = -1;		memset((char *)buf,0,PKTLEN_128);		sprintf(buf,"%s",xip->fname);		pktlen = xip->pktlen;		xip->pktlen = PKTLEN_128;		putPacket(buf,xip);		xip->pktlen = pktlen;	}        */	done = 0;	xip->sno = 1;	xip->pktcnt = 0;	while(!done) {		c = (uchar)putPacket((uchar *)(xip->dataddr),xip);		switch(c) {		case ACK:			xip->sno++;			xip->pktcnt++;			xip->size -= xip->pktlen;			xip->dataddr += xip->pktlen;			//Mtrace("A");			break;		case NAK:			//Mtrace("N");			break;		case CAN:			done = -1;			//Mtrace("C");			break;		case EOT:			done = -1;			//Mtrace("E");			break;		default:			done = -1;			//Mtrace("<%2x>",c);			break;		}		if (xip->size <= 0) {			rputchar(EOT);			getchar();	/* Flush the ACK */			break;		}		//Mtrace("!");	}	//Mtrace("Xup_almost");	/*	if ((done != -1) && (xip->flags & YMODEM)) { 		xip->sno = 0;		memset((char *)buf,0,PKTLEN_128);		pktlen = xip->pktlen;		xip->pktlen = PKTLEN_128;		putPacket(buf,xip);		xip->pktlen = pktlen;	}	*/	//Mtrace("Xup_done.");	return(0);}/* Xdown(): * Called when a transfer from host to target is being made (considered * an download). */static int Xdown(struct xinfo *xip){	long	timeout;	char	c, *tmppkt;	int	done;         /*	tmppkt = malloc(PKTLEN_1K);	if (!tmppkt) {		//Mtrace("malloc failed");		return(-1);	}        */nextfile:	/*if (xip->flags & YMODEM)		xip->sno = 0x00;	else*/		xip->sno = 0x01;	xip->pktcnt = 0;	xip->errcnt = 0;	xip->xfertot = 0;	xip->firsterrat = 0;	/* Startup synchronization... */	/* Continuously send NAK or 'C' until sender responds. */restart:	//Mtrace("Xdown");	while(1) {		if (xip->flags & USECRC)			rputchar('C');		else			rputchar(NAK);		timeout = LoopsPerSecond * xip->nakresend;		while(!gotachar() && timeout)			timeout--;		if (timeout)			break;	}	done = 0;	//Mtrace("Got response");	while(done == 0) {		c = (char)getchar();		switch(c) {		case SOH:				/* 128-byte incoming packet */			//Mtrace("O");			xip->pktlen = 128;			done = getPacket(tmppkt,xip);			if (done < 0)				//Mtrace("GP_%d",done);			if (!done && (xip->pktcnt == 1) && (xip->flags & YMODEM))				goto restart;			break;		case STX:				/* 1024-byte incoming packet */			//Mtrace("T");			xip->pktlen = 1024;			done = getPacket(tmppkt,xip);			if (done < 0)				//Mtrace("GP_%d",done);			if (!done && (xip->pktcnt == 1) && (xip->flags & YMODEM))				goto restart;			break;		case CAN:			//Mtrace("C");			done = -1;			break;		case EOT:			//Mtrace("E");			rputchar(ACK);/*						if (xip->flags & YMODEM) {#if INCLUDE_TFS				if (!xip->size)					xip->size = xip->pktcnt * xip->pktlen;				if (xip->fname[0])					tfsadd(xip->fname,0,0,(uchar *)xip->base,xip->size);				xip->dataddr = xip->base;#endif				goto nextfile;			}			else {*/				done = xip->xfertot;				printf("\nRcvd %d pkt%c (%d bytes)\n",xip->pktcnt,				xip->pktcnt > 1 ? 's' : ' ',xip->xfertot);		 		/* If the transfer is complete and no file add is to				 * be done, then we flush d-cache and invalidate				 * i-cache across the memory space that was just				 * copied to.  This is necessary in case the		 		 * binary data that was just transferred is code.				 */				/*				flushDcache((char *)xip->base,xip->xfertot);				invalidateIcache((char *)xip->base,xip->xfertot);										}*/						break;		case ESC:		/* User-invoked abort */			//Mtrace("X");			done = -1;			break;		default:			//Mtrace("<%02x>",c);			done = -1;			break;		}		//Mtrace("!");	}	if (xip->flags & VERIFY) {		if (xip->errcnt)			printf("%d errors, first at 0x%lx\n",				xip->errcnt,(ulong)(xip->firsterrat));		else			printf("verification passed\n");	}	free(tmppkt);	return(done);}

⌨️ 快捷键说明

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