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

📄 zm.c

📁 Embedded zModem C sources
💻 C
📖 第 1 页 / 共 2 页
字号:
						c = GCOUNT;
						return zRcvFin(c);
					}
					/* start again from header */
					bRxZPAD = bRxZDLE = bRxZHdr = 0;
					nCanCount = 5;
					break;
				}
				gfCrc32 = 1;	/* for RcvData check */
				c = zRcvBinHdr32(pHdrFlag, nRxHdrLen);
				bRxZHdr = 1;	/* escape from while */ 
				break;
			case ZBIN32 :
				if(gfUseVHdrs)
				{	/* invalid header type */
					if(--nGarbageCnt == 0)
					{
						c = GCOUNT;
						return zRcvFin(c);
					}
					/* start again from header */
					bRxZPAD = bRxZDLE = bRxZHdr = 0;
					nCanCount = 5;
					break;
				}
				gfCrc32 = 1;	/* for RcvData check */
				c = zRcvBinHdr32(pHdrFlag, nRxHdrLen);
				bRxZHdr = 1;	/* escape from while */ 
				break;
			case ZVBINR32 :
				if((nRxHdrLen = c = zDLERead()) < 0)
					return zRcvFin(c);
				if(c > ZMAXHLEN)
				{	/* invalid header length */ 
					if(--nGarbageCnt == 0)
					{
						c = GCOUNT;
						return zRcvFin(c);
					}
					/* start again from header */
					bRxZPAD = bRxZDLE = bRxZHdr = 0;
					nCanCount = 5;
					break;
				}
				gfCrc32 = 2;	/* for RcvData check */
				c = zRcvBinHdr32(pHdrFlag, nRxHdrLen);
				bRxZHdr = 1;	/* escape from while */ 
				break;
			case ZBINR32 :
				if(gfUseVHdrs)
				{	/* invalid header type */
					if(--nGarbageCnt == 0)
					{
						c = GCOUNT;
						return zRcvFin(c);
					}
					/* start again from header */
					bRxZPAD = bRxZDLE = bRxZHdr = 0;
					nCanCount = 5;
					break;
				}
				gfCrc32 = 2;	/* for RcvData check */
				c = zRcvBinHdr32(pHdrFlag, nRxHdrLen);
				bRxZHdr = 1;	/* escape from while */ 
				break;
			case RCD0 :
			case TIMEOUT :
				return zRcvFin(c);
			case ZVBIN :
				if((nRxHdrLen = c = zDLERead()) < 0)
					return zRcvFin(c);
				if(c > ZMAXHLEN)
				{	/* invalid header length */ 
					if(--nGarbageCnt == 0)
					{
						c = GCOUNT;
						return zRcvFin(c);
					}
					/* start again from header */
					bRxZPAD = bRxZDLE = bRxZHdr = 0;
					nCanCount = 5;
					break;
				}
				gfCrc32 = 0;	/* for RcvData check */
				c = zRcvBinHdr(pHdrFlag, nRxHdrLen);
				bRxZHdr = 1;	/* escape from while */ 
				break;
			case ZBIN :
				if(gfUseVHdrs)
				{	/* invalid header type */
					if(--nGarbageCnt == 0)
					{
						c = GCOUNT;
						return zRcvFin(c);
					}
					/* start again from header */
					bRxZPAD = bRxZDLE = bRxZHdr = 0;
					nCanCount = 5;
					break;
				}
				gfCrc32 = 0;	/* for RcvData check */
				c = zRcvBinHdr(pHdrFlag, nRxHdrLen);
				bRxZHdr = 1;	/* escape from while */ 
				break;
			case ZVHEX :
				if((nRxHdrLen = c = zGetHex()) < 0)
					return zRcvFin(c);
				if(c > ZMAXHLEN)
				{	/* invalid header length */ 
					if(--nGarbageCnt == 0)
					{
						c = GCOUNT;
						return zRcvFin(c);
					}
					/* start again from header */
					bRxZPAD = bRxZDLE = bRxZHdr = 0;
					nCanCount = 5;
					break;
				}
				gfCrc32 = 0;	/* for RcvData check */
				c = zRcvHexHdr(pHdrFlag, nRxHdrLen);
				bRxZHdr = 1;	/* escape from while */ 
				break;
			case ZHEX :
				if(gfUseVHdrs)
				{	/* invalid header type */
					if(--nGarbageCnt == 0)
					{
						c = GCOUNT;
						return zRcvFin(c);
					}
					/* start again from header */
					bRxZPAD = bRxZDLE = bRxZHdr = 0;
					nCanCount = 5;
					break;
				}
				gfCrc32 = 0;
				c = zRcvHexHdr(pHdrFlag, nRxHdrLen);
				bRxZHdr = 1;	/* escape from while */ 
				break;
			case CAN :
				goto gotcan;
				break;
			default :
				/* invalid header type : start over again */
				if(--nGarbageCnt == 0)
				{
					c = GCOUNT;
					return zRcvFin(c);
				}
				/* start again from header */
				bRxZPAD = bRxZDLE = bRxZHdr = 0;
				nCanCount = 5;
				break;
		}	/* switch(hdrType) */
	}	/* while(!bRxHdr) */
	
	/* clear unused pHdrFlag bytes */
	for(n=nRxHdrLen; ++n < ZMAXHLEN;)
		pHdrFlag[n] = 0;
	lRxPos = pHdrFlag[ZP3] & 0377;
	lRxPos = (lRxPos << 8) + (pHdrFlag[ZP2] & 0377);
	lRxPos = (lRxPos << 8) + (pHdrFlag[ZP1] & 0377);
	lRxPos = (lRxPos << 8) + (pHdrFlag[ZP0] & 0377);


	/* use variable length headers if we got one */
	if(c >= 0 && c <= ZSTDERR && (nRxFrameInd & 040))
		gfUseVHdrs = 1;
	return c;
}

int zRcvFin(int c)
{
	return c;
}

///////////////////////////////////////////////////////////////////////////////
// int zRcvBinHdr(char *pHdrFlag, int nHdrLen)
// Receive a binary style(type 'A')
// ( * ZDLE A TYPE F3/P0 F2/P1 F1/P2 F0/P3 CRC-1 CRC-2)
// 
// NB : TYPE, 4 pos bytes, two bytes of CRC are all ZDLE encoded.

int zRcvBinHdr(char *pHdrFlag, int nHdrLen)
{
	int c, n;
	unsigned short usCrc;
	int nRxHdrType;

	/* type */ 
	if((c = zDLERead()) & ~0377)
		return c;
	nRxHdrType = c;
	usCrc = updcrc(c, 0);
	
	/* 4 position/flag bytes */
	for(n=nHdrLen; --n>= 0; ++pHdrFlag)
	{
		if((c = zDLERead()) & ~0377)
			return c;
		usCrc = updcrc(c, usCrc);
		*pHdrFlag = c;
	}
	
	/* crc-1 */
	if((c = zDLERead()) & ~0377)
		return c;
	usCrc = updcrc(c, usCrc);
	
	/* crc-2 */
	if((c = zDLERead()) & ~0377)
		return c;
	usCrc = updcrc(c, usCrc);
	
	if(usCrc & 0xFFFF)
	{	/* crc error */
		return ERROR;
	}

	return nRxHdrType;
}

///////////////////////////////////////////////////////////////////////////////
// int zRcvBinHdr32(char *pHdrFlag, int nHdrLen)
// Receive a binary style(type 'A') with 32 bit FCS
// ( * ZDLE A TYPE F3/P0 F2/P1 F1/P2 F0/P3 CRC-1 CRC-2)
// 
// NB : TYPE, 4 pos bytes, four bytes of CRC are all ZDLE encoded.

int zRcvBinHdr32(char *pHdrFlag, int nHdrLen)
{
	int c, n;
	unsigned long ulCrc;
	int nRxHdrType;

	/* type */ 
	if((c = zDLERead()) & ~0377)
		return c;
	nRxHdrType = c;
	ulCrc = 0xFFFFFFFFl;
	ulCrc = UPDC32(c, ulCrc);
	
	/* 4 position/flag bytes */
	for(n=nHdrLen; --n>= 0; ++pHdrFlag)
	{
		if((c = zDLERead()) & ~0377)
			return c;
		ulCrc = UPDC32(c, ulCrc);
		*pHdrFlag = c;
	}
	
	/* crc four bytes */
	for(n=4; --n >=0; )
	{
		if((c = zDLERead()) & ~0377)
			return c;
		ulCrc = UPDC32(c, ulCrc);
	}

	if(ulCrc != 0xDEBB20E3)
	{	/* crc error */
		return ERROR;
	}

	return nRxHdrType;
}

///////////////////////////////////////////////////////////////////////////////
// int zRcvHexHdr(char *pHdrFlag, int nHdrLen)
// Receive a hex style(type 'B')
// ( * * ZDLE B TYPE F3/P0 F2/P1 F1/P2 F0/P3 CRC-1 CRC-2 CR LF XON )
// 
// NB : TYPE, four pos bytes, and two bytes of CRC are each sent as two hex digits.
// 
int zRcvHexHdr(char *pHdrFlag, int nHdrLen)
{
	int c, n;
	unsigned short usCrc;
	int 	nRxHdrType;		/* Type of header received */ 
	
	/* type */ 
	if((c = zGetHex()) < 0)
	{
		return c;
	}
	nRxHdrType = c;
	usCrc = updcrc(c, 0);	// for later use crc

	/* 4 position/flag bytes */
	for(n=nHdrLen; --n>= 0; ++pHdrFlag)
	{
		if((c = zGetHex()) < 0)
		{
			return c;
		}
		usCrc = updcrc(c, usCrc);
		*pHdrFlag = c;
	}
	/* crc-1 */
	if((c = zGetHex()) < 0)
	{
		return c;
	}
	usCrc = updcrc(c, usCrc);

	/* crc-2 */
	if((c = zGetHex()) < 0)
	{
		return c;
	}
	usCrc = updcrc(c, usCrc);

	if(usCrc & 0xFFFF)
	{	/* crc error */
		return ERROR;
	}

	/* CR/LF XON */
	if((c = ReadLine(RX_TIMEOUT)) < 0)
	{
		return c;
	}
	
	if((c = ReadLine(RX_TIMEOUT)) < 0)
	{
		return c;
	}
	return nRxHdrType;
}

///////////////////////////////////////////////////////////////////////////////
// int zDLERead(void)
// Read a byte, checking for ZMODEM escaped(ZDLE) encoding
// including CNA*5 which represents a quick abort.
// return : 32 ~127 = non-escaped character recieved.
//          GOTCAN = five successive CAN(030) character.
         
int zDLERead(void)
{
	int c;
	int bRcvZDLE = 0;

	while(!bRcvZDLE)
	{	/* until ZDLE receved or non-escaped characters */
		if((c = ReadLine(RX_TIMEOUT)) & 0140)	/* non-escpaed character(32 ~127) */
			return c;
		switch(c)
		{
			case ZDLE : 
				bRcvZDLE = 1;
				break;
			case 023 :
			case 0223 :
			case 021 :
			case 0221 :
				break;	/* ignores */
			default : 
				if(gzCtlEsc && !(c & 0140))	// if escaped character
					break;		// ignores
				else
					return c;	
		}
	}
	// process ZDLE sequence and also check CAN*5?
	while(1)
	{
		if((c = ReadLine(RX_TIMEOUT)) < 0)
			return c;
		if(c == CAN && (c = ReadLine(RX_TIMEOUT)) < 0)
			return c;
		if(c == CAN && (c = ReadLine(RX_TIMEOUT)) < 0)
			return c;
		if(c == CAN && (c = ReadLine(RX_TIMEOUT)) < 0)
			return c;
		switch(c)
		{
			case CAN : 
				return GOTCAN;
			/* valid ZDLE seequence */
			case ZCRCE :
			case ZCRCG :
			case ZCRCQ : 
			case ZCRCW :
				return (c | GOTOR);
			case ZRUB0 :	/* translated to 0177 */
				return 0177;
			case ZRUB1 :	/* translated to 0377 */
				return 0377;
			/* until here valid ZDLE seequence */
			case 023 :
			case 0223 :
			case 021 :
			case 0221 :
				break;	// ignore
			default :
				if(gzCtlEsc && !(c & 0140))
					break;		// ignore
				if((c & 0140) == 0100)
					return (c ^ 0100);
				// in this case, error
				return ERROR;
		}
	}
}

///////////////////////////////////////////////////////////////////////////////
// int zGetHex(void)
// Decode two lower case hex digits into an 8-bit byte value 

int zGetHex(void)
{
	int c;
	int n, n2;
	
	if((c = zReadChar()) < 0)
	{
		return c;
	}
	n = c - '0';
	if(n > 9)
		n -= ('a' - ':');
	if(n & ~0xF)
	{
		return ERROR;
	}
	if((c = zReadChar()) < 0)
	{
		return c;
	}
	n2 = c - '0';
	if(n2 > 9)
		n2 -= ('a' - ':');
	if(n2 & ~0xF)
	{
		return ERROR;
	}
//	c += (n << 4);
	c = n2 + (n << 4);
	return c;
}

///////////////////////////////////////////////////////////////////////////////
// int zPutHex(int c)
// Send a byte as two hex digits

int zPutHex(int c)
{
	static char digits[] = "0123456789abcdef";

	SendLine(digits[(c&0xF0)>>4]);
	SendLine(digits[(c)&0xF]);

	return 0;
}

///////////////////////////////////////////////////////////////////////////////
// zReadChar(void)
// read a character from the modem line with timeout.
// eat parity, XON and XOFF characters.

int zReadChar(void)
{
	int c;

	while(1)
	{
		if((c = ReadLine(RX_TIMEOUT)) < 0)
			return c;
		c &= 0177;		/* eat parity */
		switch(c)
		{
			case XON :
			case XOFF :
				continue;
			default :
				if(gzCtlEsc && !(c & 0140))
				{
					continue;
				}
			case '\r' :
			case '\n' :
			case ZDLE : 
				return c;
		}
	}
}

///////////////////////////////////////////////////////////////////////////////
// zLongToChar4(char *pChar, long lPos)
// store long integer in char[4]

void zLongToChar4(char *pChar, long lLong)
{
	pChar[ZP0] = (lLong  & 0377);
	pChar[ZP1] = (lLong>>8)  & 0377;
	pChar[ZP2] = (lLong>>16)  & 0377;
	pChar[ZP3] = (lLong>>24)  & 0377;

	return;
}

///////////////////////////////////////////////////////////////////////////////
// zChar4ToLong(char *hdr)
// recover a long integer from char[4]

long zChar4ToLong(char *pChar)
{
	register long l;

	l = (pChar[ZP3] & 0377);
	l = (l << 8) | (pChar[ZP2] & 0377);
	l = (l << 8) | (pChar[ZP1] & 0377);
	l = (l << 8) | (pChar[ZP0] & 0377);

	return l;
}

#endif//zmodem

⌨️ 快捷键说明

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